Skip to content

Commit b7bf324

Browse files
committed
Merge branch 'main' of https://github.com/foss42/apidash into add-rust-curl-codegen
2 parents 9cdfafb + eaedca0 commit b7bf324

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+642
-328
lines changed

lib/consts.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,8 @@ const kRaiseIssue =
501501
const kCsvError =
502502
"There seems to be an issue rendering this CSV. Please raise an issue in API Dash GitHub repo so that we can resolve it.";
503503

504-
const kHintTextUrlCard = "Enter API endpoint like api.foss42.com/country/codes";
504+
const kHintTextUrlCard =
505+
"Enter API endpoint like api.apidash.dev/country/codes";
505506
const kLabelPlusNew = "+ New";
506507
const kLabelSend = "Send";
507508
const kLabelSending = "Sending..";

lib/models/request_model.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class RequestModel {
2929
this.responseStatus,
3030
this.message,
3131
this.responseModel,
32+
this.isWorking = false,
3233
});
3334

3435
final String id;
@@ -47,6 +48,7 @@ class RequestModel {
4748
final int? responseStatus;
4849
final String? message;
4950
final ResponseModel? responseModel;
51+
final bool isWorking;
5052

5153
List<NameValueModel>? get enabledRequestHeaders =>
5254
getEnabledRows(requestHeaders, isHeaderEnabledList);
@@ -106,6 +108,7 @@ class RequestModel {
106108
int? responseStatus,
107109
String? message,
108110
ResponseModel? responseModel,
111+
bool? isWorking,
109112
}) {
110113
var headers = requestHeaders ?? this.requestHeaders;
111114
var params = requestParams ?? this.requestParams;
@@ -129,6 +132,7 @@ class RequestModel {
129132
responseStatus: responseStatus ?? this.responseStatus,
130133
message: message ?? this.message,
131134
responseModel: responseModel ?? this.responseModel,
135+
isWorking: isWorking ?? this.isWorking,
132136
);
133137
}
134138

lib/providers/collection_providers.dart

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,20 @@ class CollectionStateNotifier
156156
}
157157

158158
Future<void> sendRequest(String id) async {
159-
ref.read(sentRequestIdStateProvider.notifier).state = id;
160159
ref.read(codePaneVisibleStateProvider.notifier).state = false;
161-
final defaultUriScheme =
162-
ref.read(settingsProvider.select((value) => value.defaultUriScheme));
160+
final defaultUriScheme = ref.read(
161+
settingsProvider.select(
162+
(value) => value.defaultUriScheme,
163+
),
164+
);
165+
163166
RequestModel requestModel = state![id]!;
167+
168+
// set current model's isWorking to true and update state
169+
var map = {...state!};
170+
map[id] = requestModel.copyWith(isWorking: true);
171+
state = map;
172+
164173
(http.Response?, Duration?, String?)? responseRec = await request(
165174
requestModel,
166175
defaultUriScheme: defaultUriScheme,
@@ -172,6 +181,7 @@ class CollectionStateNotifier
172181
newRequestModel = requestModel.copyWith(
173182
responseStatus: -1,
174183
message: responseRec.$3,
184+
isWorking: false,
175185
);
176186
} else {
177187
final responseModel = baseResponseModel.fromResponse(
@@ -183,10 +193,12 @@ class CollectionStateNotifier
183193
responseStatus: statusCode,
184194
message: kResponseCodeReasons[statusCode],
185195
responseModel: responseModel,
196+
isWorking: false,
186197
);
187198
}
188-
ref.read(sentRequestIdStateProvider.notifier).state = null;
189-
var map = {...state!};
199+
200+
// update state with response data
201+
map = {...state!};
190202
map[id] = newRequestModel;
191203
state = map;
192204
}

lib/providers/ui_providers.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
33

44
final navRailIndexStateProvider = StateProvider<int>((ref) => 0);
55
final selectedIdEditStateProvider = StateProvider<String?>((ref) => null);
6-
final sentRequestIdStateProvider = StateProvider<String?>((ref) => null);
76
final codePaneVisibleStateProvider = StateProvider<bool>((ref) => false);
87
final saveDataStateProvider = StateProvider<bool>((ref) => false);
98
final clearDataStateProvider = StateProvider<bool>((ref) => false);

lib/screens/home_page/editor_pane/details_card/response_pane.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ class ResponsePane extends ConsumerWidget {
99

1010
@override
1111
Widget build(BuildContext context, WidgetRef ref) {
12-
final selectedId = ref.watch(selectedIdStateProvider);
13-
final sentRequestId = ref.watch(sentRequestIdStateProvider);
12+
final isWorking = ref.watch(
13+
selectedRequestModelProvider.select((value) => value?.isWorking)) ??
14+
false;
1415
final responseStatus = ref.watch(
1516
selectedRequestModelProvider.select((value) => value?.responseStatus));
1617
final message = ref
1718
.watch(selectedRequestModelProvider.select((value) => value?.message));
18-
if (sentRequestId != null && sentRequestId == selectedId) {
19+
if (isWorking) {
1920
return const SendingWidget();
2021
}
2122
if (responseStatus == null) {

lib/screens/home_page/editor_pane/editor_request.dart

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter_riverpod/flutter_riverpod.dart';
3+
import 'package:apidash/providers/collection_providers.dart';
24
import 'package:apidash/consts.dart';
35
import 'details_card/details_card.dart';
46
import 'url_card.dart';
@@ -10,6 +12,7 @@ class RequestEditor extends StatelessWidget {
1012
Widget build(BuildContext context) {
1113
return const Column(
1214
children: [
15+
RequestEditorTopBar(),
1316
EditorPaneRequestURLCard(),
1417
kVSpacer10,
1518
Expanded(
@@ -19,3 +22,91 @@ class RequestEditor extends StatelessWidget {
1922
);
2023
}
2124
}
25+
26+
class RequestEditorTopBar extends ConsumerWidget {
27+
const RequestEditorTopBar({super.key});
28+
29+
@override
30+
Widget build(BuildContext context, WidgetRef ref) {
31+
final id = ref.watch(selectedIdStateProvider);
32+
final name =
33+
ref.watch(selectedRequestModelProvider.select((value) => value?.name));
34+
return Padding(
35+
padding: const EdgeInsets.only(
36+
left: 12.0,
37+
top: 4.0,
38+
right: 8.0,
39+
bottom: 4.0,
40+
),
41+
child: Row(
42+
children: [
43+
Expanded(
44+
child: Text(
45+
name ?? "",
46+
style: Theme.of(context).textTheme.bodyMedium,
47+
overflow: TextOverflow.ellipsis,
48+
maxLines: 1,
49+
),
50+
),
51+
const SizedBox(
52+
width: 6,
53+
),
54+
SizedBox(
55+
width: 90,
56+
height: 24,
57+
child: FilledButton.tonalIcon(
58+
style: const ButtonStyle(
59+
padding: MaterialStatePropertyAll(EdgeInsets.zero),
60+
),
61+
onPressed: () {
62+
showDialog(
63+
context: context,
64+
builder: (context) {
65+
final controller =
66+
TextEditingController(text: name ?? "");
67+
controller.selection = TextSelection(
68+
baseOffset: 0, extentOffset: controller.text.length);
69+
return AlertDialog(
70+
title: const Text('Rename Request'),
71+
content: TextField(
72+
autofocus: true,
73+
controller: controller,
74+
decoration:
75+
const InputDecoration(hintText: "Enter new name"),
76+
),
77+
actions: <Widget>[
78+
OutlinedButton(
79+
onPressed: () {
80+
Navigator.pop(context);
81+
},
82+
child: const Text('CANCEL')),
83+
FilledButton(
84+
onPressed: () {
85+
final val = controller.text.trim();
86+
ref
87+
.read(collectionStateNotifierProvider
88+
.notifier)
89+
.update(id!, name: val);
90+
Navigator.pop(context);
91+
controller.dispose();
92+
},
93+
child: const Text('OK')),
94+
],
95+
);
96+
});
97+
},
98+
icon: const Icon(
99+
Icons.edit,
100+
size: 12,
101+
),
102+
label: Text(
103+
"Rename",
104+
style: Theme.of(context).textTheme.bodySmall,
105+
),
106+
),
107+
)
108+
],
109+
),
110+
);
111+
}
112+
}

lib/screens/home_page/editor_pane/url_card.dart

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ class URLTextField extends ConsumerWidget {
8181
.read(collectionStateNotifierProvider.notifier)
8282
.update(selectedId, url: value);
8383
},
84+
onFieldSubmitted: (value) {
85+
ref
86+
.read(collectionStateNotifierProvider.notifier)
87+
.sendRequest(selectedId);
88+
},
8489
);
8590
}
8691
}
@@ -93,10 +98,11 @@ class SendButton extends ConsumerWidget {
9398
@override
9499
Widget build(BuildContext context, WidgetRef ref) {
95100
final selectedId = ref.watch(selectedIdStateProvider);
96-
final sentRequestId = ref.watch(sentRequestIdStateProvider);
101+
final isWorking = ref.watch(
102+
selectedRequestModelProvider.select((value) => value?.isWorking));
103+
97104
return SendRequestButton(
98-
selectedId: selectedId,
99-
sentRequestId: sentRequestId,
105+
isWorking: isWorking ?? false,
100106
onTap: () {
101107
ref
102108
.read(collectionStateNotifierProvider.notifier)

lib/screens/settings_page.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class SettingsPage extends ConsumerWidget {
6565
hoverColor: kColorTransparent,
6666
title: const Text('Default URI Scheme'),
6767
subtitle: Text(
68-
'api.foss42.com → ${settings.defaultUriScheme}://api.foss42.com'),
68+
'api.apidash.dev → ${settings.defaultUriScheme}://api.apidash.dev'),
6969
trailing: DropdownMenu(
7070
onSelected: (value) {
7171
ref

lib/utils/file_utils.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ String getShortPath(String path) {
4343
var f = p.split(path);
4444
if (f.length > 2) {
4545
f = f.sublist(f.length - 2);
46-
return ".../${p.joinAll(f)}";
46+
return p.join("...", p.joinAll(f));
4747
}
4848
return path;
4949
}

lib/widgets/buttons.dart

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,36 +47,37 @@ class CopyButton extends StatelessWidget {
4747
class SendRequestButton extends StatelessWidget {
4848
const SendRequestButton({
4949
super.key,
50-
required this.selectedId,
51-
required this.sentRequestId,
50+
required this.isWorking,
5251
required this.onTap,
5352
});
5453

55-
final String? selectedId;
56-
final String? sentRequestId;
54+
final bool isWorking;
5755
final void Function() onTap;
5856

5957
@override
6058
Widget build(BuildContext context) {
61-
bool disable = sentRequestId != null;
6259
return FilledButton(
63-
onPressed: disable ? null : onTap,
60+
onPressed: isWorking ? null : onTap,
6461
child: Row(
6562
mainAxisSize: MainAxisSize.min,
66-
children: [
67-
Text(
68-
disable
69-
? (selectedId == sentRequestId ? kLabelSending : kLabelBusy)
70-
: kLabelSend,
71-
style: kTextStyleButton,
72-
),
73-
if (!disable) kHSpacer10,
74-
if (!disable)
75-
const Icon(
76-
size: 16,
77-
Icons.send,
78-
),
79-
],
63+
children: isWorking
64+
? const [
65+
Text(
66+
kLabelSending,
67+
style: kTextStyleButton,
68+
),
69+
]
70+
: const [
71+
Text(
72+
kLabelSend,
73+
style: kTextStyleButton,
74+
),
75+
kHSpacer10,
76+
Icon(
77+
size: 16,
78+
Icons.send,
79+
),
80+
],
8081
),
8182
);
8283
}

0 commit comments

Comments
 (0)