mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 02:39:19 +08:00
SSE: Stopping/Cancelling implementation
This commit is contained in:
@@ -22,6 +22,7 @@ class RequestModel with _$RequestModel {
|
|||||||
HttpResponseModel? httpResponseModel,
|
HttpResponseModel? httpResponseModel,
|
||||||
@JsonKey(includeToJson: false) @Default(false) bool isWorking,
|
@JsonKey(includeToJson: false) @Default(false) bool isWorking,
|
||||||
@JsonKey(includeToJson: false) DateTime? sendingTime,
|
@JsonKey(includeToJson: false) DateTime? sendingTime,
|
||||||
|
@JsonKey(includeToJson: false) @Default(false) bool isStreaming,
|
||||||
String? preRequestScript,
|
String? preRequestScript,
|
||||||
String? postRequestScript,
|
String? postRequestScript,
|
||||||
}) = _RequestModel;
|
}) = _RequestModel;
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ mixin _$RequestModel {
|
|||||||
bool get isWorking => throw _privateConstructorUsedError;
|
bool get isWorking => throw _privateConstructorUsedError;
|
||||||
@JsonKey(includeToJson: false)
|
@JsonKey(includeToJson: false)
|
||||||
DateTime? get sendingTime => throw _privateConstructorUsedError;
|
DateTime? get sendingTime => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(includeToJson: false)
|
||||||
|
bool get isStreaming => throw _privateConstructorUsedError;
|
||||||
String? get preRequestScript => throw _privateConstructorUsedError;
|
String? get preRequestScript => throw _privateConstructorUsedError;
|
||||||
String? get postRequestScript => throw _privateConstructorUsedError;
|
String? get postRequestScript => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
@@ -66,6 +68,7 @@ abstract class $RequestModelCopyWith<$Res> {
|
|||||||
HttpResponseModel? httpResponseModel,
|
HttpResponseModel? httpResponseModel,
|
||||||
@JsonKey(includeToJson: false) bool isWorking,
|
@JsonKey(includeToJson: false) bool isWorking,
|
||||||
@JsonKey(includeToJson: false) DateTime? sendingTime,
|
@JsonKey(includeToJson: false) DateTime? sendingTime,
|
||||||
|
@JsonKey(includeToJson: false) bool isStreaming,
|
||||||
String? preRequestScript,
|
String? preRequestScript,
|
||||||
String? postRequestScript});
|
String? postRequestScript});
|
||||||
|
|
||||||
@@ -99,6 +102,7 @@ class _$RequestModelCopyWithImpl<$Res, $Val extends RequestModel>
|
|||||||
Object? httpResponseModel = freezed,
|
Object? httpResponseModel = freezed,
|
||||||
Object? isWorking = null,
|
Object? isWorking = null,
|
||||||
Object? sendingTime = freezed,
|
Object? sendingTime = freezed,
|
||||||
|
Object? isStreaming = null,
|
||||||
Object? preRequestScript = freezed,
|
Object? preRequestScript = freezed,
|
||||||
Object? postRequestScript = freezed,
|
Object? postRequestScript = freezed,
|
||||||
}) {
|
}) {
|
||||||
@@ -147,6 +151,10 @@ class _$RequestModelCopyWithImpl<$Res, $Val extends RequestModel>
|
|||||||
? _value.sendingTime
|
? _value.sendingTime
|
||||||
: sendingTime // ignore: cast_nullable_to_non_nullable
|
: sendingTime // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
|
isStreaming: null == isStreaming
|
||||||
|
? _value.isStreaming
|
||||||
|
: isStreaming // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
preRequestScript: freezed == preRequestScript
|
preRequestScript: freezed == preRequestScript
|
||||||
? _value.preRequestScript
|
? _value.preRequestScript
|
||||||
: preRequestScript // ignore: cast_nullable_to_non_nullable
|
: preRequestScript // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -207,6 +215,7 @@ abstract class _$$RequestModelImplCopyWith<$Res>
|
|||||||
HttpResponseModel? httpResponseModel,
|
HttpResponseModel? httpResponseModel,
|
||||||
@JsonKey(includeToJson: false) bool isWorking,
|
@JsonKey(includeToJson: false) bool isWorking,
|
||||||
@JsonKey(includeToJson: false) DateTime? sendingTime,
|
@JsonKey(includeToJson: false) DateTime? sendingTime,
|
||||||
|
@JsonKey(includeToJson: false) bool isStreaming,
|
||||||
String? preRequestScript,
|
String? preRequestScript,
|
||||||
String? postRequestScript});
|
String? postRequestScript});
|
||||||
|
|
||||||
@@ -240,6 +249,7 @@ class __$$RequestModelImplCopyWithImpl<$Res>
|
|||||||
Object? httpResponseModel = freezed,
|
Object? httpResponseModel = freezed,
|
||||||
Object? isWorking = null,
|
Object? isWorking = null,
|
||||||
Object? sendingTime = freezed,
|
Object? sendingTime = freezed,
|
||||||
|
Object? isStreaming = null,
|
||||||
Object? preRequestScript = freezed,
|
Object? preRequestScript = freezed,
|
||||||
Object? postRequestScript = freezed,
|
Object? postRequestScript = freezed,
|
||||||
}) {
|
}) {
|
||||||
@@ -287,6 +297,10 @@ class __$$RequestModelImplCopyWithImpl<$Res>
|
|||||||
? _value.sendingTime
|
? _value.sendingTime
|
||||||
: sendingTime // ignore: cast_nullable_to_non_nullable
|
: sendingTime // ignore: cast_nullable_to_non_nullable
|
||||||
as DateTime?,
|
as DateTime?,
|
||||||
|
isStreaming: null == isStreaming
|
||||||
|
? _value.isStreaming
|
||||||
|
: isStreaming // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
preRequestScript: freezed == preRequestScript
|
preRequestScript: freezed == preRequestScript
|
||||||
? _value.preRequestScript
|
? _value.preRequestScript
|
||||||
: preRequestScript // ignore: cast_nullable_to_non_nullable
|
: preRequestScript // ignore: cast_nullable_to_non_nullable
|
||||||
@@ -315,6 +329,7 @@ class _$RequestModelImpl implements _RequestModel {
|
|||||||
this.httpResponseModel,
|
this.httpResponseModel,
|
||||||
@JsonKey(includeToJson: false) this.isWorking = false,
|
@JsonKey(includeToJson: false) this.isWorking = false,
|
||||||
@JsonKey(includeToJson: false) this.sendingTime,
|
@JsonKey(includeToJson: false) this.sendingTime,
|
||||||
|
@JsonKey(includeToJson: false) this.isStreaming = false,
|
||||||
this.preRequestScript,
|
this.preRequestScript,
|
||||||
this.postRequestScript});
|
this.postRequestScript});
|
||||||
|
|
||||||
@@ -350,13 +365,16 @@ class _$RequestModelImpl implements _RequestModel {
|
|||||||
@JsonKey(includeToJson: false)
|
@JsonKey(includeToJson: false)
|
||||||
final DateTime? sendingTime;
|
final DateTime? sendingTime;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey(includeToJson: false)
|
||||||
|
final bool isStreaming;
|
||||||
|
@override
|
||||||
final String? preRequestScript;
|
final String? preRequestScript;
|
||||||
@override
|
@override
|
||||||
final String? postRequestScript;
|
final String? postRequestScript;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'RequestModel(id: $id, apiType: $apiType, name: $name, description: $description, requestTabIndex: $requestTabIndex, httpRequestModel: $httpRequestModel, responseStatus: $responseStatus, message: $message, httpResponseModel: $httpResponseModel, isWorking: $isWorking, sendingTime: $sendingTime, preRequestScript: $preRequestScript, postRequestScript: $postRequestScript)';
|
return 'RequestModel(id: $id, apiType: $apiType, name: $name, description: $description, requestTabIndex: $requestTabIndex, httpRequestModel: $httpRequestModel, responseStatus: $responseStatus, message: $message, httpResponseModel: $httpResponseModel, isWorking: $isWorking, sendingTime: $sendingTime, isStreaming: $isStreaming, preRequestScript: $preRequestScript, postRequestScript: $postRequestScript)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -382,6 +400,8 @@ class _$RequestModelImpl implements _RequestModel {
|
|||||||
other.isWorking == isWorking) &&
|
other.isWorking == isWorking) &&
|
||||||
(identical(other.sendingTime, sendingTime) ||
|
(identical(other.sendingTime, sendingTime) ||
|
||||||
other.sendingTime == sendingTime) &&
|
other.sendingTime == sendingTime) &&
|
||||||
|
(identical(other.isStreaming, isStreaming) ||
|
||||||
|
other.isStreaming == isStreaming) &&
|
||||||
(identical(other.preRequestScript, preRequestScript) ||
|
(identical(other.preRequestScript, preRequestScript) ||
|
||||||
other.preRequestScript == preRequestScript) &&
|
other.preRequestScript == preRequestScript) &&
|
||||||
(identical(other.postRequestScript, postRequestScript) ||
|
(identical(other.postRequestScript, postRequestScript) ||
|
||||||
@@ -403,6 +423,7 @@ class _$RequestModelImpl implements _RequestModel {
|
|||||||
httpResponseModel,
|
httpResponseModel,
|
||||||
isWorking,
|
isWorking,
|
||||||
sendingTime,
|
sendingTime,
|
||||||
|
isStreaming,
|
||||||
preRequestScript,
|
preRequestScript,
|
||||||
postRequestScript);
|
postRequestScript);
|
||||||
|
|
||||||
@@ -435,6 +456,7 @@ abstract class _RequestModel implements RequestModel {
|
|||||||
final HttpResponseModel? httpResponseModel,
|
final HttpResponseModel? httpResponseModel,
|
||||||
@JsonKey(includeToJson: false) final bool isWorking,
|
@JsonKey(includeToJson: false) final bool isWorking,
|
||||||
@JsonKey(includeToJson: false) final DateTime? sendingTime,
|
@JsonKey(includeToJson: false) final DateTime? sendingTime,
|
||||||
|
@JsonKey(includeToJson: false) final bool isStreaming,
|
||||||
final String? preRequestScript,
|
final String? preRequestScript,
|
||||||
final String? postRequestScript}) = _$RequestModelImpl;
|
final String? postRequestScript}) = _$RequestModelImpl;
|
||||||
|
|
||||||
@@ -467,6 +489,9 @@ abstract class _RequestModel implements RequestModel {
|
|||||||
@JsonKey(includeToJson: false)
|
@JsonKey(includeToJson: false)
|
||||||
DateTime? get sendingTime;
|
DateTime? get sendingTime;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey(includeToJson: false)
|
||||||
|
bool get isStreaming;
|
||||||
|
@override
|
||||||
String? get preRequestScript;
|
String? get preRequestScript;
|
||||||
@override
|
@override
|
||||||
String? get postRequestScript;
|
String? get postRequestScript;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ _$RequestModelImpl _$$RequestModelImplFromJson(Map json) => _$RequestModelImpl(
|
|||||||
sendingTime: json['sendingTime'] == null
|
sendingTime: json['sendingTime'] == null
|
||||||
? null
|
? null
|
||||||
: DateTime.parse(json['sendingTime'] as String),
|
: DateTime.parse(json['sendingTime'] as String),
|
||||||
|
isStreaming: json['isStreaming'] as bool? ?? false,
|
||||||
preRequestScript: json['preRequestScript'] as String?,
|
preRequestScript: json['preRequestScript'] as String?,
|
||||||
postRequestScript: json['postRequestScript'] as String?,
|
postRequestScript: json['postRequestScript'] as String?,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -270,19 +270,16 @@ class CollectionStateNotifier
|
|||||||
Future<void> sendRequest() async {
|
Future<void> sendRequest() async {
|
||||||
final requestId = ref.read(selectedIdStateProvider);
|
final requestId = ref.read(selectedIdStateProvider);
|
||||||
ref.read(codePaneVisibleStateProvider.notifier).state = false;
|
ref.read(codePaneVisibleStateProvider.notifier).state = false;
|
||||||
|
|
||||||
|
if (requestId == null || state == null) return;
|
||||||
|
|
||||||
|
RequestModel? requestModel = state![requestId];
|
||||||
|
if (requestModel?.httpRequestModel == null) return;
|
||||||
|
|
||||||
final defaultUriScheme = ref.read(settingsProvider).defaultUriScheme;
|
final defaultUriScheme = ref.read(settingsProvider).defaultUriScheme;
|
||||||
final EnvironmentModel? originalEnvironmentModel =
|
final EnvironmentModel? originalEnvironmentModel =
|
||||||
ref.read(selectedEnvironmentModelProvider);
|
ref.read(selectedEnvironmentModelProvider);
|
||||||
|
|
||||||
if (requestId == null || state == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RequestModel? requestModel = state![requestId];
|
|
||||||
|
|
||||||
if (requestModel?.httpRequestModel == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestModel != null &&
|
if (requestModel != null &&
|
||||||
!requestModel.preRequestScript.isNullOrEmpty()) {
|
!requestModel.preRequestScript.isNullOrEmpty()) {
|
||||||
requestModel = await handlePreRequestScript(
|
requestModel = await handlePreRequestScript(
|
||||||
@@ -303,23 +300,18 @@ class CollectionStateNotifier
|
|||||||
APIType apiType = requestModel!.apiType;
|
APIType apiType = requestModel!.apiType;
|
||||||
HttpRequestModel substitutedHttpRequestModel =
|
HttpRequestModel substitutedHttpRequestModel =
|
||||||
getSubstitutedHttpRequestModel(requestModel.httpRequestModel!);
|
getSubstitutedHttpRequestModel(requestModel.httpRequestModel!);
|
||||||
|
|
||||||
// set current model's isWorking to true and update state
|
|
||||||
var map = {...state!};
|
|
||||||
map[requestId] = requestModel.copyWith(
|
|
||||||
isWorking: true,
|
|
||||||
sendingTime: DateTime.now(),
|
|
||||||
);
|
|
||||||
state = map;
|
|
||||||
|
|
||||||
bool noSSL = ref.read(settingsProvider).isSSLDisabled;
|
bool noSSL = ref.read(settingsProvider).isSSLDisabled;
|
||||||
|
|
||||||
(Response?, Duration?, String?) responseRec;
|
// Set model to working and streaming
|
||||||
HttpResponseModel? respModel;
|
state = {
|
||||||
HistoryRequestModel? historyM;
|
...state!,
|
||||||
RequestModel? newRequestModel;
|
requestId: requestModel.copyWith(
|
||||||
|
isWorking: true,
|
||||||
|
isStreaming: true,
|
||||||
|
sendingTime: DateTime.now(),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
responseRec = (null, null, null);
|
|
||||||
final stream = await streamHttpRequest(
|
final stream = await streamHttpRequest(
|
||||||
requestId,
|
requestId,
|
||||||
apiType,
|
apiType,
|
||||||
@@ -328,101 +320,98 @@ class CollectionStateNotifier
|
|||||||
noSSL: noSSL,
|
noSSL: noSSL,
|
||||||
);
|
);
|
||||||
|
|
||||||
StreamSubscription? sub;
|
HttpResponseModel? respModel;
|
||||||
final completer = Completer();
|
HistoryRequestModel? historyM;
|
||||||
|
RequestModel newRequestModel = requestModel;
|
||||||
|
final completer = Completer<(Response?, Duration?, String?)>();
|
||||||
bool isTextStream = false;
|
bool isTextStream = false;
|
||||||
|
StreamSubscription? sub;
|
||||||
|
|
||||||
sub = stream.listen((d) async {
|
sub = stream.listen((d) async {
|
||||||
if (d == null) return;
|
if (d == null) return;
|
||||||
|
|
||||||
isTextStream = ((d.$1 == null && isTextStream) ||
|
final contentType = d.$1;
|
||||||
(d.$1 == 'text/event-stream' || d.$1 == 'application/x-ndjson'));
|
isTextStream = isTextStream ||
|
||||||
|
contentType == 'text/event-stream' ||
|
||||||
|
contentType == 'application/x-ndjson';
|
||||||
|
|
||||||
responseRec = (d.$2, d.$3, d.$4);
|
final response = d.$2;
|
||||||
|
final duration = d.$3;
|
||||||
|
final errorMessage = d.$4;
|
||||||
|
|
||||||
if (!isTextStream) {
|
if (!isTextStream) {
|
||||||
if (completer.isCompleted) return;
|
if (!completer.isCompleted) {
|
||||||
completer.complete(responseRec);
|
completer.complete((response, duration, errorMessage));
|
||||||
await Future.delayed(Duration(milliseconds: 100));
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (responseRec.$1 != null) {
|
respModel = respModel?.copyWith(
|
||||||
responseRec = (
|
sseOutput: [
|
||||||
HttpResponse(
|
|
||||||
responseRec.$1!.body,
|
|
||||||
responseRec.$1!.statusCode,
|
|
||||||
request: responseRec.$1!.request,
|
|
||||||
headers: {
|
|
||||||
...(responseRec.$1?.headers ?? {}),
|
|
||||||
'content-type': 'text/event-stream'
|
|
||||||
},
|
|
||||||
isRedirect: responseRec.$1!.isRedirect,
|
|
||||||
reasonPhrase: responseRec.$1!.reasonPhrase,
|
|
||||||
persistentConnection: responseRec.$1!.persistentConnection,
|
|
||||||
),
|
|
||||||
responseRec.$2,
|
|
||||||
responseRec.$3,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------- MAKE CHANGES --------------
|
|
||||||
respModel = respModel?.copyWith(sseOutput: [
|
|
||||||
...(respModel?.sseOutput ?? []),
|
...(respModel?.sseOutput ?? []),
|
||||||
responseRec.$1!.body,
|
if (response != null) response.body,
|
||||||
]);
|
],
|
||||||
if (respModel != null) {
|
);
|
||||||
final nRM = newRequestModel!.copyWith(
|
|
||||||
|
newRequestModel = newRequestModel.copyWith(
|
||||||
httpResponseModel: respModel,
|
httpResponseModel: respModel,
|
||||||
|
isStreaming: true,
|
||||||
);
|
);
|
||||||
map = {...state!};
|
state = {
|
||||||
map[requestId] = nRM;
|
...state!,
|
||||||
state = map;
|
requestId: newRequestModel,
|
||||||
|
};
|
||||||
unsave();
|
unsave();
|
||||||
}
|
|
||||||
//Changing History
|
|
||||||
if (historyM != null && respModel != null) {
|
if (historyM != null && respModel != null) {
|
||||||
historyM = historyM!.copyWith(
|
historyM = historyM!.copyWith(httpResponseModel: respModel!);
|
||||||
httpResponseModel: respModel!,
|
|
||||||
);
|
|
||||||
ref
|
ref
|
||||||
.read(historyMetaStateNotifier.notifier)
|
.read(historyMetaStateNotifier.notifier)
|
||||||
.editHistoryRequest(historyM!);
|
.editHistoryRequest(historyM!);
|
||||||
}
|
}
|
||||||
//----------- MAKE CHANGES --------------
|
|
||||||
|
|
||||||
if (completer.isCompleted) return;
|
if (!completer.isCompleted) {
|
||||||
completer.complete(responseRec);
|
completer.complete((response, duration, errorMessage));
|
||||||
|
}
|
||||||
}, onDone: () {
|
}, onDone: () {
|
||||||
sub?.cancel();
|
sub?.cancel();
|
||||||
|
state = {
|
||||||
|
...state!,
|
||||||
|
requestId: newRequestModel.copyWith(isStreaming: false),
|
||||||
|
};
|
||||||
|
unsave();
|
||||||
}, onError: (e) {
|
}, onError: (e) {
|
||||||
print('err: $e');
|
print('Stream error: $e');
|
||||||
});
|
});
|
||||||
responseRec = await completer.future;
|
|
||||||
|
|
||||||
if (responseRec.$1 == null) {
|
final (response, duration, errorMessage) = await completer.future;
|
||||||
newRequestModel = requestModel.copyWith(
|
|
||||||
|
if (response == null) {
|
||||||
|
newRequestModel = newRequestModel.copyWith(
|
||||||
responseStatus: -1,
|
responseStatus: -1,
|
||||||
message: responseRec.$3,
|
message: errorMessage,
|
||||||
isWorking: false,
|
isWorking: false,
|
||||||
|
isStreaming: false,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
final statusCode = response.statusCode;
|
||||||
respModel = baseHttpResponseModel.fromResponse(
|
respModel = baseHttpResponseModel.fromResponse(
|
||||||
response: responseRec.$1!,
|
response: response,
|
||||||
time: responseRec.$2!,
|
time: duration,
|
||||||
);
|
);
|
||||||
int statusCode = responseRec.$1!.statusCode;
|
|
||||||
newRequestModel = requestModel.copyWith(
|
newRequestModel = newRequestModel.copyWith(
|
||||||
responseStatus: statusCode,
|
responseStatus: statusCode,
|
||||||
message: kResponseCodeReasons[statusCode],
|
message: kResponseCodeReasons[statusCode],
|
||||||
httpResponseModel: respModel,
|
httpResponseModel: respModel,
|
||||||
isWorking: false,
|
isWorking: false,
|
||||||
);
|
);
|
||||||
String newHistoryId = getNewUuid();
|
|
||||||
|
final historyId = getNewUuid();
|
||||||
historyM = HistoryRequestModel(
|
historyM = HistoryRequestModel(
|
||||||
historyId: newHistoryId,
|
historyId: historyId,
|
||||||
metaData: HistoryMetaModel(
|
metaData: HistoryMetaModel(
|
||||||
historyId: newHistoryId,
|
historyId: historyId,
|
||||||
requestId: requestId,
|
requestId: requestId,
|
||||||
apiType: requestModel.apiType,
|
apiType: requestModel.apiType,
|
||||||
name: requestModel.name,
|
name: requestModel.name,
|
||||||
@@ -452,13 +441,15 @@ class CollectionStateNotifier
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref.read(historyMetaStateNotifier.notifier).addHistoryRequest(historyM!);
|
ref.read(historyMetaStateNotifier.notifier).addHistoryRequest(historyM!);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update state with response data
|
// Final state update
|
||||||
map = {...state!};
|
state = {
|
||||||
map[requestId] = newRequestModel;
|
...state!,
|
||||||
state = map;
|
requestId: newRequestModel,
|
||||||
|
};
|
||||||
|
|
||||||
unsave();
|
unsave();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,8 +129,11 @@ class SendRequestButton extends ConsumerWidget {
|
|||||||
ref.watch(selectedIdStateProvider);
|
ref.watch(selectedIdStateProvider);
|
||||||
final isWorking = ref.watch(
|
final isWorking = ref.watch(
|
||||||
selectedRequestModelProvider.select((value) => value?.isWorking));
|
selectedRequestModelProvider.select((value) => value?.isWorking));
|
||||||
|
final isStreaming = ref.watch(
|
||||||
|
selectedRequestModelProvider.select((value) => value?.isStreaming));
|
||||||
|
|
||||||
return SendButton(
|
return SendButton(
|
||||||
|
isStreaming: isStreaming ?? false,
|
||||||
isWorking: isWorking ?? false,
|
isWorking: isWorking ?? false,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
onTap?.call();
|
onTap?.call();
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import 'package:apidash/consts.dart';
|
|||||||
class SendButton extends StatelessWidget {
|
class SendButton extends StatelessWidget {
|
||||||
const SendButton({
|
const SendButton({
|
||||||
super.key,
|
super.key,
|
||||||
|
required this.isStreaming,
|
||||||
required this.isWorking,
|
required this.isWorking,
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
this.onCancel,
|
this.onCancel,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final bool isStreaming;
|
||||||
final bool isWorking;
|
final bool isWorking;
|
||||||
final void Function() onTap;
|
final void Function() onTap;
|
||||||
final void Function()? onCancel;
|
final void Function()? onCancel;
|
||||||
@@ -17,13 +19,13 @@ class SendButton extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ADFilledButton(
|
return ADFilledButton(
|
||||||
onPressed: isWorking ? onCancel : onTap,
|
onPressed: (isWorking || isStreaming) ? onCancel : onTap,
|
||||||
isTonal: isWorking ? true : false,
|
isTonal: (isWorking || isStreaming),
|
||||||
items: isWorking
|
items: (isWorking || isStreaming)
|
||||||
? const [
|
? [
|
||||||
kHSpacer8,
|
kHSpacer8,
|
||||||
Text(
|
Text(
|
||||||
kLabelCancel,
|
isStreaming ? 'Stop' : kLabelCancel,
|
||||||
style: kTextStyleButton,
|
style: kTextStyleButton,
|
||||||
),
|
),
|
||||||
kHSpacer6,
|
kHSpacer6,
|
||||||
|
|||||||
@@ -247,8 +247,6 @@ streamHttpRequest(
|
|||||||
final streamedResponse = await client.send(multipart);
|
final streamedResponse = await client.send(multipart);
|
||||||
final stream = streamTextResponse(streamedResponse);
|
final stream = streamTextResponse(streamedResponse);
|
||||||
|
|
||||||
print(streamedResponse.headers['content-type']);
|
|
||||||
|
|
||||||
subscription = stream.listen(
|
subscription = stream.listen(
|
||||||
(data) => controller.add((
|
(data) => controller.add((
|
||||||
streamedResponse.headers['content-type'].toString(),
|
streamedResponse.headers['content-type'].toString(),
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ void main() {
|
|||||||
home: Scaffold(
|
home: Scaffold(
|
||||||
body: SendButton(
|
body: SendButton(
|
||||||
isWorking: false,
|
isWorking: false,
|
||||||
|
isStreaming: false,
|
||||||
onTap: () => sendPressed = true,
|
onTap: () => sendPressed = true,
|
||||||
onCancel: () => cancelPressed = true,
|
onCancel: () => cancelPressed = true,
|
||||||
),
|
),
|
||||||
@@ -46,6 +47,7 @@ void main() {
|
|||||||
home: Scaffold(
|
home: Scaffold(
|
||||||
body: SendButton(
|
body: SendButton(
|
||||||
isWorking: true,
|
isWorking: true,
|
||||||
|
isStreaming: false,
|
||||||
onTap: () => sendPressed = true,
|
onTap: () => sendPressed = true,
|
||||||
onCancel: () => cancelPressed = true,
|
onCancel: () => cancelPressed = true,
|
||||||
),
|
),
|
||||||
@@ -74,6 +76,7 @@ void main() {
|
|||||||
builder: (context, setState) {
|
builder: (context, setState) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: SendButton(
|
body: SendButton(
|
||||||
|
isStreaming: false,
|
||||||
isWorking: isWorking,
|
isWorking: isWorking,
|
||||||
onTap: () => setState(() => isWorking = true),
|
onTap: () => setState(() => isWorking = true),
|
||||||
onCancel: () => setState(() => isWorking = false),
|
onCancel: () => setState(() => isWorking = false),
|
||||||
|
|||||||
Reference in New Issue
Block a user