mirror of
https://github.com/foss42/apidash.git
synced 2025-12-01 18:28:25 +08:00
Refactor SSE response handling and display
Updated response body widgets to handle SSE output as a list of strings instead of a single string. Adjusted view options for SSE-related media types and refactored SSEDisplay to be a stateless widget that accepts a list of SSE events. This improves clarity and consistency in handling and displaying SSE responses.
This commit is contained in:
@@ -183,6 +183,10 @@ const kPreviewCodeRawBodyViewOptions = [
|
||||
ResponseBodyView.code,
|
||||
ResponseBodyView.raw
|
||||
];
|
||||
const kPreviewSSERawBodyViewOptions = [
|
||||
ResponseBodyView.sse,
|
||||
ResponseBodyView.raw
|
||||
];
|
||||
|
||||
const Map<String, Map<String, List<ResponseBodyView>>>
|
||||
kResponseBodyViewOptions = {
|
||||
@@ -196,6 +200,15 @@ const Map<String, Map<String, List<ResponseBodyView>>>
|
||||
kSubTypeYaml: kCodeRawBodyViewOptions,
|
||||
kSubTypeXYaml: kCodeRawBodyViewOptions,
|
||||
kSubTypeYml: kCodeRawBodyViewOptions,
|
||||
kSubTypeXNdjson: kPreviewSSERawBodyViewOptions,
|
||||
kSubTypeNdjson: kPreviewSSERawBodyViewOptions,
|
||||
kSubTypeJsonSeq: kPreviewSSERawBodyViewOptions,
|
||||
kSubTypeXLdjson: kPreviewSSERawBodyViewOptions,
|
||||
kSubTypeLdjson: kPreviewSSERawBodyViewOptions,
|
||||
kSubTypeXJsonStream: kPreviewSSERawBodyViewOptions,
|
||||
kSubTypeJsonStream: kPreviewSSERawBodyViewOptions,
|
||||
kSubTypeJsonstream: kPreviewSSERawBodyViewOptions,
|
||||
kSubTypeStreamJson: kPreviewSSERawBodyViewOptions,
|
||||
},
|
||||
kTypeImage: {
|
||||
kSubTypeDefaultViewOptions: kPreviewBodyViewOptions,
|
||||
@@ -217,6 +230,7 @@ const Map<String, Map<String, List<ResponseBodyView>>>
|
||||
kSubTypeTextXml: kCodeRawBodyViewOptions,
|
||||
kSubTypeTextYaml: kCodeRawBodyViewOptions,
|
||||
kSubTypeTextYml: kCodeRawBodyViewOptions,
|
||||
kSubTypeEventStream: kPreviewSSERawBodyViewOptions,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:apidash_core/apidash_core.dart';
|
||||
import 'package:apidash/models/models.dart';
|
||||
@@ -24,6 +22,7 @@ class ResponseBody extends StatelessWidget {
|
||||
message: '$kNullResponseModelError $kUnexpectedRaiseIssue');
|
||||
}
|
||||
|
||||
final isSSE = responseModel.sseOutput?.isNotEmpty ?? false;
|
||||
var body = responseModel.body;
|
||||
var formattedBody = responseModel.formattedBody;
|
||||
if (body == null) {
|
||||
@@ -37,6 +36,9 @@ class ResponseBody extends StatelessWidget {
|
||||
showIssueButton: false,
|
||||
);
|
||||
}
|
||||
if (isSSE) {
|
||||
body = responseModel.sseOutput!.join();
|
||||
}
|
||||
|
||||
final mediaType =
|
||||
responseModel.mediaType ?? MediaType(kTypeText, kSubTypePlain);
|
||||
@@ -56,20 +58,6 @@ class ResponseBody extends StatelessWidget {
|
||||
options.remove(ResponseBodyView.code);
|
||||
}
|
||||
|
||||
// print('reM -> ${responseModel.sseOutput}');
|
||||
|
||||
if (responseModel.sseOutput?.isNotEmpty ?? false) {
|
||||
// final modifiedBody = responseModel.sseOutput!.join('\n\n');
|
||||
return ResponseBodySuccess(
|
||||
key: Key("${selectedRequestModel!.id}-response"),
|
||||
mediaType: MediaType('text', 'event-stream'),
|
||||
options: [ResponseBodyView.sse, ResponseBodyView.raw],
|
||||
bytes: utf8.encode((responseModel.sseOutput!).toString()),
|
||||
body: jsonEncode(responseModel.sseOutput!),
|
||||
formattedBody: responseModel.sseOutput!.join('\n'),
|
||||
);
|
||||
}
|
||||
|
||||
return ResponseBodySuccess(
|
||||
key: Key("${selectedRequestModel!.id}-response"),
|
||||
mediaType: mediaType,
|
||||
@@ -77,6 +65,7 @@ class ResponseBody extends StatelessWidget {
|
||||
bytes: responseModel.bodyBytes!,
|
||||
body: body,
|
||||
formattedBody: formattedBody,
|
||||
sseOutput: responseModel.sseOutput,
|
||||
highlightLanguage: highlightLanguage,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,13 +15,16 @@ class ResponseBodySuccess extends StatefulWidget {
|
||||
required this.options,
|
||||
required this.bytes,
|
||||
this.formattedBody,
|
||||
this.sseOutput,
|
||||
this.highlightLanguage});
|
||||
final MediaType mediaType;
|
||||
final List<ResponseBodyView> options;
|
||||
final String body;
|
||||
final Uint8List bytes;
|
||||
final String? formattedBody;
|
||||
final List<String>? sseOutput;
|
||||
final String? highlightLanguage;
|
||||
|
||||
@override
|
||||
State<ResponseBodySuccess> createState() => _ResponseBodySuccessState();
|
||||
}
|
||||
@@ -150,7 +153,7 @@ class _ResponseBodySuccessState extends State<ResponseBodySuccess> {
|
||||
padding: kP8,
|
||||
decoration: textContainerdecoration,
|
||||
child: SSEDisplay(
|
||||
sseOutput: widget.body,
|
||||
sseOutput: widget.sseOutput,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -2,26 +2,21 @@ import 'dart:convert';
|
||||
import 'package:apidash_design_system/apidash_design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SSEDisplay extends StatefulWidget {
|
||||
final String sseOutput;
|
||||
const SSEDisplay({super.key, required this.sseOutput});
|
||||
class SSEDisplay extends StatelessWidget {
|
||||
final List<String>? sseOutput;
|
||||
const SSEDisplay({
|
||||
super.key,
|
||||
this.sseOutput,
|
||||
});
|
||||
|
||||
@override
|
||||
State<SSEDisplay> createState() => _SSEDisplayState();
|
||||
}
|
||||
|
||||
class _SSEDisplayState extends State<SSEDisplay> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final fontSizeMedium = theme.textTheme.bodyMedium?.fontSize;
|
||||
final isDark = theme.brightness == Brightness.dark;
|
||||
List<dynamic> sse;
|
||||
try {
|
||||
sse = jsonDecode(widget.sseOutput);
|
||||
} catch (e) {
|
||||
if (sseOutput == null || sseOutput!.isEmpty) {
|
||||
return Text(
|
||||
'Invalid SSE output',
|
||||
'No content',
|
||||
style: kCodeStyle.copyWith(
|
||||
fontSize: fontSizeMedium,
|
||||
color: isDark ? kColorDarkDanger : kColorLightDanger,
|
||||
@@ -31,7 +26,7 @@ class _SSEDisplayState extends State<SSEDisplay> {
|
||||
|
||||
return ListView(
|
||||
padding: kP1,
|
||||
children: sse.reversed.where((e) => e != '').map<Widget>((chunk) {
|
||||
children: sseOutput!.reversed.where((e) => e != '').map<Widget>((chunk) {
|
||||
Map<String, dynamic>? parsedJson;
|
||||
try {
|
||||
parsedJson = jsonDecode(chunk);
|
||||
|
||||
Reference in New Issue
Block a user