mirror of
https://github.com/foss42/apidash.git
synced 2025-06-03 00:14:06 +08:00
Merge branch 'main' into add-feature-22
This commit is contained in:
1
devtools_options.yaml
Normal file
1
devtools_options.yaml
Normal file
@ -0,0 +1 @@
|
||||
extensions:
|
@ -48,6 +48,7 @@ const kHintOpacity = 0.6;
|
||||
const kForegroundOpacity = 0.05;
|
||||
|
||||
const kTextStyleButton = TextStyle(fontWeight: FontWeight.bold);
|
||||
const kTextStyleButtonSmall = TextStyle(fontSize: 12);
|
||||
const kFormDataButtonLabelTextStyle = TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
|
@ -54,7 +54,7 @@ class EditRequestHeadersState extends ConsumerState<EditRequestHeaders> {
|
||||
columns: [
|
||||
DaviColumn(
|
||||
name: 'Checkbox',
|
||||
width: 36,
|
||||
width: 30,
|
||||
cellBuilder: (_, row) {
|
||||
int idx = row.index;
|
||||
return CheckBox(
|
||||
@ -72,6 +72,7 @@ class EditRequestHeadersState extends ConsumerState<EditRequestHeaders> {
|
||||
),
|
||||
DaviColumn(
|
||||
name: 'Header Name',
|
||||
width: 70,
|
||||
grow: 1,
|
||||
cellBuilder: (_, row) {
|
||||
int idx = row.index;
|
||||
|
@ -55,7 +55,7 @@ class EditRequestURLParamsState extends ConsumerState<EditRequestURLParams> {
|
||||
columns: [
|
||||
DaviColumn(
|
||||
name: 'Checkbox',
|
||||
width: 36,
|
||||
width: 30,
|
||||
cellBuilder: (_, row) {
|
||||
int idx = row.index;
|
||||
|
||||
@ -74,6 +74,7 @@ class EditRequestURLParamsState extends ConsumerState<EditRequestURLParams> {
|
||||
),
|
||||
DaviColumn(
|
||||
name: 'URL Parameter',
|
||||
width: 70,
|
||||
grow: 1,
|
||||
cellBuilder: (_, row) {
|
||||
int idx = row.index;
|
||||
|
@ -59,3 +59,13 @@ Color getDarkModeColor(Color col) {
|
||||
kColorWhite,
|
||||
);
|
||||
}
|
||||
|
||||
double? getJsonPreviewerMaxRootNodeWidth(double w) {
|
||||
if (w < 300) {
|
||||
return 150;
|
||||
}
|
||||
if (w < 400) {
|
||||
return 200;
|
||||
}
|
||||
return w - 150;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
import '../consts.dart';
|
||||
import '../utils/ui_utils.dart';
|
||||
import "snackbars.dart";
|
||||
import 'textfields.dart';
|
||||
|
||||
@ -151,120 +152,151 @@ class _JsonPreviewerState extends State<JsonPreviewer> {
|
||||
store.expandAll();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(JsonPreviewer oldWidget) {
|
||||
if (oldWidget.code != widget.code) {
|
||||
store.buildNodes(widget.code, areAllCollapsed: true);
|
||||
store.expandAll();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var sm = ScaffoldMessenger.of(context);
|
||||
return ChangeNotifierProvider.value(
|
||||
value: store,
|
||||
child: Consumer<DataExplorerStore>(
|
||||
builder: (context, state, child) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
await _copy(kEncoder.convert(widget.code), sm);
|
||||
},
|
||||
child: const Text('Copy'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: state.areAllExpanded() ? null : state.expandAll,
|
||||
child: const Text('Expand All'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: state.areAllCollapsed() ? null : state.collapseAll,
|
||||
child: const Text('Collapse All'),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: JsonDataExplorer(
|
||||
nodes: state.displayNodes,
|
||||
itemScrollController: itemScrollController,
|
||||
itemSpacing: 4,
|
||||
rootInformationBuilder: (context, node) =>
|
||||
rootInfoBox(context, node),
|
||||
collapsableToggleBuilder: (context, node) => AnimatedRotation(
|
||||
turns: node.isCollapsed ? -0.25 : 0,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: const Icon(Icons.arrow_drop_down),
|
||||
),
|
||||
trailingBuilder: (context, node) => node.isFocused
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints: const BoxConstraints(maxHeight: 18),
|
||||
icon: const Icon(
|
||||
Icons.copy,
|
||||
size: 18,
|
||||
),
|
||||
onPressed: () async {
|
||||
await _copy(kEncoder.convert(toJson(node)), sm);
|
||||
},
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
valueStyleBuilder: (value, style) =>
|
||||
valueStyleOverride(context, value, style),
|
||||
theme: (Theme.of(context).brightness == Brightness.light)
|
||||
? dataExplorerThemeLight
|
||||
: dataExplorerThemeDark,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.surfaceVariant),
|
||||
borderRadius: kBorderRadius8,
|
||||
),
|
||||
child: Row(
|
||||
builder: (context, state, child) {
|
||||
return LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
var maxRootNodeWidth =
|
||||
getJsonPreviewerMaxRootNodeWidth(constraints.maxWidth);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Icon(
|
||||
Icons.search,
|
||||
size: 18,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
await _copy(kEncoder.convert(widget.code), sm);
|
||||
},
|
||||
child: const Text(
|
||||
'Copy',
|
||||
style: kTextStyleButtonSmall,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed:
|
||||
state.areAllExpanded() ? null : state.expandAll,
|
||||
child: const Text(
|
||||
'Expand All',
|
||||
style: kTextStyleButtonSmall,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed:
|
||||
state.areAllCollapsed() ? null : state.collapseAll,
|
||||
child: const Text(
|
||||
'Collapse All',
|
||||
style: kTextStyleButtonSmall,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: JsonSearchField(
|
||||
controller: searchController,
|
||||
onChanged: (term) => state.search(term),
|
||||
child: JsonDataExplorer(
|
||||
nodes: state.displayNodes,
|
||||
itemScrollController: itemScrollController,
|
||||
itemSpacing: 4,
|
||||
rootInformationBuilder: (context, node) =>
|
||||
rootInfoBox(context, node),
|
||||
collapsableToggleBuilder: (context, node) =>
|
||||
AnimatedRotation(
|
||||
turns: node.isCollapsed ? -0.25 : 0,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: const Icon(Icons.arrow_drop_down),
|
||||
),
|
||||
trailingBuilder: (context, node) => node.isFocused
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
constraints:
|
||||
const BoxConstraints(maxHeight: 18),
|
||||
icon: const Icon(
|
||||
Icons.copy,
|
||||
size: 18,
|
||||
),
|
||||
onPressed: () async {
|
||||
await _copy(
|
||||
kEncoder.convert(toJson(node)), sm);
|
||||
},
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
valueStyleBuilder: (value, style) =>
|
||||
valueStyleOverride(context, value, style),
|
||||
theme: (Theme.of(context).brightness == Brightness.light)
|
||||
? dataExplorerThemeLight
|
||||
: dataExplorerThemeDark,
|
||||
maxRootNodeWidth: maxRootNodeWidth,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.surfaceVariant),
|
||||
borderRadius: kBorderRadius8,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Icon(
|
||||
Icons.search,
|
||||
size: 18,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: JsonSearchField(
|
||||
controller: searchController,
|
||||
onChanged: (term) => state.search(term),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
if (state.searchResults.isNotEmpty)
|
||||
Text(_searchFocusText(),
|
||||
style: Theme.of(context).textTheme.bodySmall),
|
||||
if (state.searchResults.isNotEmpty)
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
onPressed: () {
|
||||
store.focusPreviousSearchResult();
|
||||
_scrollToSearchMatch();
|
||||
},
|
||||
icon: const Icon(Icons.arrow_drop_up),
|
||||
),
|
||||
if (state.searchResults.isNotEmpty)
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
onPressed: () {
|
||||
store.focusNextSearchResult();
|
||||
_scrollToSearchMatch();
|
||||
},
|
||||
icon: const Icon(Icons.arrow_drop_down),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (state.searchResults.isNotEmpty)
|
||||
Text(_searchFocusText(),
|
||||
style: Theme.of(context).textTheme.bodySmall),
|
||||
if (state.searchResults.isNotEmpty)
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
onPressed: () {
|
||||
store.focusPreviousSearchResult();
|
||||
_scrollToSearchMatch();
|
||||
},
|
||||
icon: const Icon(Icons.arrow_drop_up),
|
||||
),
|
||||
if (state.searchResults.isNotEmpty)
|
||||
IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
onPressed: () {
|
||||
store.focusNextSearchResult();
|
||||
_scrollToSearchMatch();
|
||||
},
|
||||
icon: const Icon(Icons.arrow_drop_down),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -397,6 +397,13 @@ class _BodySuccessState extends State<BodySuccess> {
|
||||
(widget.options == kRawBodyViewOptions)
|
||||
? const SizedBox()
|
||||
: SegmentedButton<ResponseBodyView>(
|
||||
style: const ButtonStyle(
|
||||
padding: MaterialStatePropertyAll(
|
||||
EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
),
|
||||
),
|
||||
),
|
||||
selectedIcon: Icon(currentSeg.icon),
|
||||
segments: widget.options
|
||||
.map<ButtonSegment<ResponseBodyView>>(
|
||||
@ -418,7 +425,7 @@ class _BodySuccessState extends State<BodySuccess> {
|
||||
const Spacer(),
|
||||
kCodeRawBodyViewOptions.contains(currentSeg)
|
||||
? CopyButton(
|
||||
toCopy: widget.body,
|
||||
toCopy: widget.formattedBody ?? widget.body,
|
||||
showLabel: showLabel,
|
||||
)
|
||||
: const SizedBox(),
|
||||
@ -474,7 +481,7 @@ class _BodySuccessState extends State<BodySuccess> {
|
||||
decoration: textContainerdecoration,
|
||||
child: SingleChildScrollView(
|
||||
child: SelectableText(
|
||||
widget.body,
|
||||
widget.formattedBody ?? widget.body,
|
||||
style: kCodeStyle,
|
||||
),
|
||||
),
|
||||
|
24
pubspec.lock
24
pubspec.lock
@ -281,6 +281,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
file_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.1"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -366,6 +374,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.18+2"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.17"
|
||||
flutter_riverpod:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -548,11 +564,11 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: HEAD
|
||||
resolved-ref: "9e279ee9862c4fc4050dbcb5074529b22e67a7c3"
|
||||
ref: "9fa58d7b51e65174ab11cbcae17bba88a4194dde"
|
||||
resolved-ref: "9fa58d7b51e65174ab11cbcae17bba88a4194dde"
|
||||
url: "https://github.com/foss42/json_data_explorer.git"
|
||||
source: git
|
||||
version: "0.1.1"
|
||||
version: "0.1.2"
|
||||
json_serializable:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -1304,5 +1320,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.2.0 <4.0.0"
|
||||
dart: ">=3.2.3 <4.0.0"
|
||||
flutter: ">=3.16.0"
|
||||
|
@ -47,7 +47,7 @@ dependencies:
|
||||
json_data_explorer:
|
||||
git:
|
||||
url: https://github.com/foss42/json_data_explorer.git
|
||||
version: ^0.1.1
|
||||
ref: 9fa58d7b51e65174ab11cbcae17bba88a4194dde
|
||||
scrollable_positioned_list: ^0.2.3
|
||||
file_picker: ^6.1.1
|
||||
flutter_svg: ^2.0.9
|
||||
|
Reference in New Issue
Block a user