fix: PR fixes with few enhancements

This commit is contained in:
Vidya Sagar
2023-12-23 22:47:53 +05:30
parent b320090378
commit 1444317d91
10 changed files with 122 additions and 129 deletions

View File

@ -1,10 +1,9 @@
import 'dart:convert';
import 'dart:io';
import 'package:davi/davi.dart';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:davi/davi.dart';
const kDiscordUrl = "https://bit.ly/heyfoss";
const kGitUrl = "https://github.com/foss42/apidash";
@ -49,6 +48,10 @@ const kHintOpacity = 0.6;
const kForegroundOpacity = 0.05;
const kTextStyleButton = TextStyle(fontWeight: FontWeight.bold);
const kFormDataButton = TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
);
const kBorderRadius8 = BorderRadius.all(Radius.circular(8));
final kBorderRadius10 = BorderRadius.circular(10);
@ -74,7 +77,7 @@ const kPh60 = EdgeInsets.symmetric(horizontal: 60);
const kP24CollectionPane = EdgeInsets.only(top: 24, left: 8.0, bottom: 8.0);
const kP8CollectionPane = EdgeInsets.only(top: 8.0, left: 8.0, bottom: 8.0);
const kPr8CollectionPane = EdgeInsets.only(right: 8.0);
const kpsV5 = EdgeInsets.symmetric(vertical: 2);
const kHSpacer4 = SizedBox(width: 4);
const kHSpacer5 = SizedBox(width: 5);
const kHSpacer10 = SizedBox(width: 10);
@ -300,14 +303,6 @@ const kContentTypeMap = {
ContentType.text: "$kTypeText/$kSubTypePlain",
ContentType.formdata: "multipart/form-data",
};
const kFormDataTypeMap = {
FormDataType.file: "file",
FormDataType.text: "text",
};
const kMapFormDataType = {
"file": FormDataType.file,
"text": FormDataType.text,
};
enum ResponseBodyView { preview, code, raw, none }

View File

@ -8,7 +8,7 @@ part 'form_data_model.g.dart';
class FormDataModel with _$FormDataModel {
const factory FormDataModel({
required String name,
required dynamic value,
required String value,
required FormDataType type,
}) = _FormDataModel;

View File

@ -21,7 +21,7 @@ FormDataModel _$FormDataModelFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$FormDataModel {
String get name => throw _privateConstructorUsedError;
dynamic get value => throw _privateConstructorUsedError;
String get value => throw _privateConstructorUsedError;
FormDataType get type => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@ -36,7 +36,7 @@ abstract class $FormDataModelCopyWith<$Res> {
FormDataModel value, $Res Function(FormDataModel) then) =
_$FormDataModelCopyWithImpl<$Res, FormDataModel>;
@useResult
$Res call({String name, dynamic value, FormDataType type});
$Res call({String name, String value, FormDataType type});
}
/// @nodoc
@ -53,7 +53,7 @@ class _$FormDataModelCopyWithImpl<$Res, $Val extends FormDataModel>
@override
$Res call({
Object? name = null,
Object? value = freezed,
Object? value = null,
Object? type = null,
}) {
return _then(_value.copyWith(
@ -61,10 +61,10 @@ class _$FormDataModelCopyWithImpl<$Res, $Val extends FormDataModel>
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
value: freezed == value
value: null == value
? _value.value
: value // ignore: cast_nullable_to_non_nullable
as dynamic,
as String,
type: null == type
? _value.type
: type // ignore: cast_nullable_to_non_nullable
@ -81,7 +81,7 @@ abstract class _$$FormDataModelImplCopyWith<$Res>
__$$FormDataModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({String name, dynamic value, FormDataType type});
$Res call({String name, String value, FormDataType type});
}
/// @nodoc
@ -96,7 +96,7 @@ class __$$FormDataModelImplCopyWithImpl<$Res>
@override
$Res call({
Object? name = null,
Object? value = freezed,
Object? value = null,
Object? type = null,
}) {
return _then(_$FormDataModelImpl(
@ -104,10 +104,10 @@ class __$$FormDataModelImplCopyWithImpl<$Res>
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
value: freezed == value
value: null == value
? _value.value
: value // ignore: cast_nullable_to_non_nullable
as dynamic,
as String,
type: null == type
? _value.type
: type // ignore: cast_nullable_to_non_nullable
@ -128,7 +128,7 @@ class _$FormDataModelImpl implements _FormDataModel {
@override
final String name;
@override
final dynamic value;
final String value;
@override
final FormDataType type;
@ -143,14 +143,13 @@ class _$FormDataModelImpl implements _FormDataModel {
(other.runtimeType == runtimeType &&
other is _$FormDataModelImpl &&
(identical(other.name, name) || other.name == name) &&
const DeepCollectionEquality().equals(other.value, value) &&
(identical(other.value, value) || other.value == value) &&
(identical(other.type, type) || other.type == type));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(
runtimeType, name, const DeepCollectionEquality().hash(value), type);
int get hashCode => Object.hash(runtimeType, name, value, type);
@JsonKey(ignore: true)
@override
@ -169,7 +168,7 @@ class _$FormDataModelImpl implements _FormDataModel {
abstract class _FormDataModel implements FormDataModel {
const factory _FormDataModel(
{required final String name,
required final dynamic value,
required final String value,
required final FormDataType type}) = _$FormDataModelImpl;
factory _FormDataModel.fromJson(Map<String, dynamic> json) =
@ -178,7 +177,7 @@ abstract class _FormDataModel implements FormDataModel {
@override
String get name;
@override
dynamic get value;
String get value;
@override
FormDataType get type;
@override

View File

@ -9,7 +9,7 @@ part of 'form_data_model.dart';
_$FormDataModelImpl _$$FormDataModelImplFromJson(Map<String, dynamic> json) =>
_$FormDataModelImpl(
name: json['name'] as String,
value: json['value'],
value: json['value'] as String,
type: $enumDecode(_$FormDataTypeEnumMap, json['type']),
);

View File

@ -2,3 +2,4 @@ export 'name_value_model.dart';
export 'request_model.dart';
export 'response_model.dart';
export 'settings_model.dart';
export 'form_data_model.dart';

View File

@ -1,5 +1,3 @@
import 'dart:math';
import 'package:apidash/consts.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/widgets/form_data_widget.dart';
@ -15,12 +13,9 @@ class EditRequestBody extends ConsumerStatefulWidget {
}
class _EditRequestBodyState extends ConsumerState<EditRequestBody> {
final random = Random.secure();
late int seed;
@override
void initState() {
super.initState();
seed = random.nextInt(kRandMax);
}
@override
@ -54,12 +49,7 @@ class _EditRequestBodyState extends ConsumerState<EditRequestBody> {
),
Expanded(
child: requestBodyStateWatcher == ContentType.formdata
? FormDataWidget(
seed: seed,
onFormDataRemove: () {
seed = random.nextInt(kRandMax);
},
)
? const FormDataWidget()
: TextFieldEditor(
key: Key("$activeId-body"),
fieldKey: "$activeId-body-editor",

View File

@ -1,12 +1,9 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:apidash/models/form_data_model.dart';
import 'package:apidash/consts.dart';
import 'package:apidash/models/models.dart';
import 'package:http/http.dart' as http;
import '../consts.dart';
import '../models/models.dart';
String humanizeDuration(Duration? duration) {
if (duration == null) {
return "";
@ -113,16 +110,24 @@ List<FormDataModel>? listToFormDataModel(List? kvMap) {
if (kvMap == null) {
return null;
}
List<FormDataModel> finalRows = kvMap
.map((formData) => FormDataModel(
List<FormDataModel> finalRows = kvMap.map(
(formData) {
return FormDataModel(
name: formData["name"],
value: formData["value"],
type: kMapFormDataType[formData["type"]] ?? FormDataType.text,
))
.toList();
type: getFormDataType(formData["type"]),
);
},
).toList();
return finalRows;
}
FormDataType getFormDataType(String? type) {
List<FormDataType> formData = FormDataType.values;
return formData.firstWhere((element) => element.name == type,
orElse: () => FormDataType.text);
}
Uint8List? stringToBytes(String? text) {
if (text == null) {
return null;

View File

@ -129,6 +129,7 @@ class _DropdownButtonFormData extends State<DropdownButtonFormData> {
Widget build(BuildContext context) {
final surfaceColor = Theme.of(context).colorScheme.surface;
return DropdownButton<FormDataType>(
dropdownColor: surfaceColor,
focusColor: surfaceColor,
value: widget.formDataType,
icon: const Icon(

View File

@ -27,10 +27,8 @@ class FormDataField extends StatefulWidget {
}
class _FormDataFieldState extends State<FormDataField> {
TextEditingController valueController = TextEditingController();
@override
void initState() {
valueController.text = widget.initialValue ?? "";
super.initState();
}
@ -42,7 +40,7 @@ class _FormDataFieldState extends State<FormDataField> {
Expanded(
flex: 1,
child: TextFormField(
controller: valueController,
initialValue: widget.initialValue,
key: Key(widget.keyId),
style: kCodeStyle.copyWith(
color: colorScheme.onSurface,
@ -66,21 +64,17 @@ class _FormDataFieldState extends State<FormDataField> {
color: colorScheme.surfaceVariant,
),
),
),
onChanged: widget.onChanged,
),
),
Expanded(
child: DropdownButtonFormData(
suffixIcon: DropdownButtonFormData(
formDataType: widget.formDataType,
onChanged: (p0) {
if (widget.onFormDataTypeChanged != null) {
widget.onFormDataTypeChanged!(p0);
valueController.clear();
}
},
)),
onChanged: widget.onChanged,
),
),
)
],
);
}

View File

@ -1,5 +1,7 @@
import 'dart:math';
import 'package:apidash/consts.dart';
import 'package:apidash/models/form_data_model.dart';
import 'package:apidash/models/models.dart';
import 'package:apidash/providers/collection_providers.dart';
import 'package:apidash/widgets/form_data_field.dart';
import 'package:apidash/widgets/textfields.dart';
@ -9,43 +11,48 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class FormDataWidget extends ConsumerStatefulWidget {
const FormDataWidget({
super.key,
required this.seed,
required this.onFormDataRemove,
});
final int seed;
final Function onFormDataRemove;
const FormDataWidget({super.key});
@override
ConsumerState<FormDataWidget> createState() => _FormDataBodyState();
}
class _FormDataBodyState extends ConsumerState<FormDataWidget> {
late int seed;
final random = Random.secure();
late List<FormDataModel> rows;
@override
void initState() {
super.initState();
seed = random.nextInt(kRandMax);
}
@override
Widget build(BuildContext context) {
final activeId = ref.watch(activeIdStateProvider);
final requestModel = ref
.read(collectionStateNotifierProvider.notifier)
.getRequestModel(activeId!);
List<FormDataModel> rows = requestModel?.formDataList ?? [];
DaviModel<FormDataModel> model = DaviModel<FormDataModel>(
var formRows = ref.read(activeRequestModelProvider)?.formDataList;
rows =
formRows == null || formRows.isEmpty ? [kFormDataEmptyModel] : formRows;
DaviModel<FormDataModel> daviModelRows = DaviModel<FormDataModel>(
rows: rows,
columns: [
DaviColumn(
cellPadding: kpsV5,
name: 'Key',
grow: 1,
cellBuilder: (_, row) {
int idx = row.index;
return SizedBox(
return Theme(
data: Theme.of(context),
child: FormDataField(
keyId: "$activeId-$idx-form-v-${widget.seed}",
keyId: "$activeId-$idx-form-v-$seed",
initialValue: rows[idx].name,
hintText: " Key",
onChanged: (value) {
rows[idx] = rows[idx].copyWith(
name: value,
);
_onFieldChange(activeId);
_onFieldChange(activeId!);
},
colorScheme: Theme.of(context).colorScheme,
formDataType: rows[idx].type,
@ -54,7 +61,8 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
type: value ?? FormDataType.text,
);
rows[idx] = rows[idx].copyWith(value: "");
_onFieldChange(activeId);
setState(() {});
_onFieldChange(activeId!);
},
),
);
@ -62,7 +70,9 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
sortable: false,
),
DaviColumn(
width: 10,
width: 30,
cellPadding: kpsV5,
cellAlignment: Alignment.center,
cellBuilder: (_, row) {
return Text(
"=",
@ -73,6 +83,7 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
DaviColumn(
name: 'Value',
grow: 4,
cellPadding: kpsV5,
cellBuilder: (_, row) {
int idx = row.index;
return rows[idx].type == FormDataType.file
@ -83,36 +94,35 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
child: Row(
children: [
Expanded(
child: ElevatedButtonTheme(
data: const ElevatedButtonThemeData(),
child: Theme(
data: Theme.of(context),
child: ElevatedButton.icon(
icon: const Icon(
Icons.snippet_folder_rounded,
size: 20,
),
style: const ButtonStyle(),
onPressed: () async {
FilePickerResult? pickedResult =
await FilePicker.platform.pickFiles();
if (pickedResult != null &&
pickedResult.files.isNotEmpty) {
pickedResult.files.isNotEmpty &&
pickedResult.files.first.path != null) {
rows[idx] = rows[idx].copyWith(
value: pickedResult.files.first.path,
value: pickedResult.files.first.path!,
);
_onFieldChange(activeId);
setState(() {});
_onFieldChange(activeId!);
}
},
icon: const Icon(
Icons.snippet_folder_rounded,
size: 18,
),
label: Text(
rows[idx].type == FormDataType.file
? (rows[idx].value != null
(rows[idx].type == FormDataType.file &&
rows[idx].value.isNotEmpty)
? rows[idx].value.toString()
: "Select File")
: "Select File",
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: kTextStyleButton.copyWith(
fontSize: 12,
fontWeight: FontWeight.w500,
),
style: kFormDataButton,
),
),
),
@ -122,12 +132,12 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
),
)
: CellField(
keyId: "$activeId-$idx-form-v-${widget.seed}",
keyId: "$activeId-$idx-form-v-$seed",
initialValue: rows[idx].value,
hintText: " Value",
onChanged: (value) {
rows[idx] = rows[idx].copyWith(value: value);
_onFieldChange(activeId);
_onFieldChange(activeId!);
},
colorScheme: Theme.of(context).colorScheme,
);
@ -143,17 +153,16 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
? kIconRemoveDark
: kIconRemoveLight,
onTap: () {
widget.onFormDataRemove();
seed = random.nextInt(kRandMax);
if (rows.length == 1) {
setState(() {
rows = [
kFormDataEmptyModel,
];
rows = [kFormDataEmptyModel];
});
} else {
rows.removeAt(row.index);
}
_onFieldChange(activeId);
_onFieldChange(activeId!);
setState(() {});
},
);
},
@ -173,7 +182,7 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
Expanded(
child: DaviTheme(
data: kTableThemeData,
child: Davi<FormDataModel>(model),
child: Davi<FormDataModel>(daviModelRows),
),
),
],
@ -185,8 +194,10 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
padding: const EdgeInsets.only(bottom: 30),
child: ElevatedButton.icon(
onPressed: () {
setState(() {
rows.add(kFormDataEmptyModel);
_onFieldChange(activeId);
});
_onFieldChange(activeId!);
},
icon: const Icon(Icons.add),
label: const Text(
@ -201,12 +212,9 @@ class _FormDataBodyState extends ConsumerState<FormDataWidget> {
}
void _onFieldChange(String activeId) {
List<FormDataModel> formDataList =
ref.read(collectionStateNotifierProvider)?[activeId]?.formDataList ??
[];
ref.read(collectionStateNotifierProvider.notifier).update(
activeId,
formDataList: formDataList,
formDataList: rows,
);
}
}