Skip to content

Commit 239b75c

Browse files
committed
chore: create separate widget for proxy dialog
1 parent 11ee7f2 commit 239b75c

File tree

5 files changed

+162
-85
lines changed

5 files changed

+162
-85
lines changed

lib/models/settings_model.dart

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class SettingsModel {
3434
final bool isSSLDisabled;
3535

3636
// Proxy settings
37-
final ProxySettings proxySettings;
37+
final ProxySettings? proxySettings;
3838

3939
SettingsModel copyWith({
4040
bool? isDark,
@@ -66,7 +66,7 @@ class SettingsModel {
6666
historyRetentionPeriod ?? this.historyRetentionPeriod,
6767
workspaceFolderPath: workspaceFolderPath ?? this.workspaceFolderPath,
6868
isSSLDisabled: isSSLDisabled ?? this.isSSLDisabled,
69-
proxySettings: proxySettings ?? this.proxySettings,
69+
proxySettings: proxySettings,
7070
);
7171
}
7272

@@ -99,13 +99,16 @@ class SettingsModel {
9999
final dx = data["dx"] as double?;
100100
final dy = data["dy"] as double?;
101101
Size? size;
102+
102103
if (width != null && height != null) {
103104
size = Size(width, height);
104105
}
105106
Offset? offset;
107+
106108
if (dx != null && dy != null) {
107109
offset = Offset(dx, dy);
108110
}
111+
109112
final defaultUriSchemeStr = data["defaultUriScheme"] as String?;
110113
SupportedUriSchemes? defaultUriScheme;
111114
if (defaultUriSchemeStr != null) {
@@ -116,6 +119,7 @@ class SettingsModel {
116119
// pass
117120
}
118121
}
122+
119123
final defaultCodeGenLangStr = data["defaultCodeGenLang"] as String?;
120124
CodegenLanguage? defaultCodeGenLang;
121125
if (defaultCodeGenLangStr != null) {
@@ -126,6 +130,7 @@ class SettingsModel {
126130
// pass
127131
}
128132
}
133+
129134
final saveResponses = data["saveResponses"] as bool?;
130135
final promptBeforeClosing = data["promptBeforeClosing"] as bool?;
131136
final activeEnvironmentId = data["activeEnvironmentId"] as String?;
@@ -139,9 +144,19 @@ class SettingsModel {
139144
// pass
140145
}
141146
}
147+
142148
final workspaceFolderPath = data["workspaceFolderPath"] as String?;
143149
final isSSLDisabled = data["isSSLDisabled"] as bool?;
144150

151+
ProxySettings? proxySettings;
152+
if (data["proxySettings"] != null) {
153+
try {
154+
proxySettings = ProxySettings.fromJson(Map<String, dynamic>.from(data["proxySettings"]));
155+
} catch (e) {
156+
// pass
157+
}
158+
}
159+
145160
const sm = SettingsModel();
146161

147162
return sm.copyWith(
@@ -158,7 +173,7 @@ class SettingsModel {
158173
historyRetentionPeriod ?? HistoryRetentionPeriod.oneWeek,
159174
workspaceFolderPath: workspaceFolderPath,
160175
isSSLDisabled: isSSLDisabled,
161-
proxySettings: ProxySettings.fromJson(data["proxySettings"]),
176+
proxySettings: proxySettings,
162177
);
163178
}
164179

@@ -178,7 +193,7 @@ class SettingsModel {
178193
"historyRetentionPeriod": historyRetentionPeriod.name,
179194
"workspaceFolderPath": workspaceFolderPath,
180195
"isSSLDisabled": isSSLDisabled,
181-
"proxySettings": proxySettings,
196+
"proxySettings": proxySettings?.toJson(),
182197
};
183198
}
184199

lib/providers/settings_providers.dart

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,26 @@ class ThemeStateNotifier extends StateNotifier<SettingsModel> {
3535
bool? isSSLDisabled,
3636
ProxySettings? proxySettings,
3737
}) async {
38-
state = state.copyWith(
39-
isDark: isDark ?? state.isDark,
40-
alwaysShowCollectionPaneScrollbar: alwaysShowCollectionPaneScrollbar ?? state.alwaysShowCollectionPaneScrollbar,
41-
size: size ?? state.size,
42-
offset: offset ?? state.offset,
43-
defaultUriScheme: defaultUriScheme ?? state.defaultUriScheme,
44-
defaultCodeGenLang: defaultCodeGenLang ?? state.defaultCodeGenLang,
45-
saveResponses: saveResponses ?? state.saveResponses,
46-
promptBeforeClosing: promptBeforeClosing ?? state.promptBeforeClosing,
47-
activeEnvironmentId: activeEnvironmentId ?? state.activeEnvironmentId,
48-
historyRetentionPeriod: historyRetentionPeriod ?? state.historyRetentionPeriod,
49-
workspaceFolderPath: workspaceFolderPath ?? state.workspaceFolderPath,
50-
isSSLDisabled: isSSLDisabled ?? state.isSSLDisabled,
51-
proxySettings: proxySettings ?? state.proxySettings,
38+
39+
final newState = state.copyWith(
40+
isDark: isDark,
41+
alwaysShowCollectionPaneScrollbar: alwaysShowCollectionPaneScrollbar,
42+
size: size,
43+
offset: offset,
44+
defaultUriScheme: defaultUriScheme,
45+
defaultCodeGenLang: defaultCodeGenLang,
46+
saveResponses: saveResponses,
47+
promptBeforeClosing: promptBeforeClosing,
48+
activeEnvironmentId: activeEnvironmentId,
49+
historyRetentionPeriod: historyRetentionPeriod,
50+
workspaceFolderPath: workspaceFolderPath,
51+
isSSLDisabled: isSSLDisabled,
52+
proxySettings: proxySettings,
5253
);
53-
await setSettingsToSharedPrefs(state);
54+
55+
if (newState != state) {
56+
state = newState;
57+
await setSettingsToSharedPrefs(state);
58+
}
5459
}
5560
}

lib/screens/settings_page.dart

Lines changed: 14 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:apidash/widgets/proxy_settings_dialog.dart';
12
import 'package:flutter/foundation.dart';
23
import 'package:flutter/material.dart';
34
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -7,7 +8,6 @@ import '../services/services.dart';
78
import '../utils/utils.dart';
89
import '../widgets/widgets.dart';
910
import '../consts.dart';
10-
import 'dart:developer' as developer;
1111

1212
class SettingsPage extends ConsumerWidget {
1313
const SettingsPage({super.key});
@@ -51,75 +51,24 @@ class SettingsPage extends ConsumerWidget {
5151
ref.read(settingsProvider.notifier).update(isDark: value);
5252
},
5353
),
54-
// Proxy Settings Section
5554
SwitchListTile(
56-
hoverColor: kColorTransparent,
57-
title: const Text('Enable Proxy'),
58-
subtitle: const Text('Configure HTTP proxy settings'),
59-
value: ref.watch(settingsProvider.select((settings) => settings.isProxyEnabled)),
60-
onChanged: (bool? value) {
61-
if (value != null) {
62-
developer.log('Toggling proxy settings', name: 'settings_page', error: 'New value: $value');
63-
ref.read(settingsProvider.notifier).update(
64-
isProxyEnabled: value,
65-
proxyHost: value ? settings.proxyHost : '',
66-
proxyPort: value ? settings.proxyPort : '',
67-
proxyUsername: value ? settings.proxyUsername : null,
68-
proxyPassword: value ? settings.proxyPassword : null,
55+
title: const Text('Proxy Settings'),
56+
subtitle: Text(ref.watch(settingsProvider).proxySettings != null
57+
? 'Enabled - ${ref.watch(settingsProvider).proxySettings!.host}:${ref.watch(settingsProvider).proxySettings!.port}'
58+
: 'Disabled'
59+
),
60+
value: ref.watch(settingsProvider).proxySettings != null,
61+
onChanged: (bool value) {
62+
if (!value) {
63+
ref.read(settingsProvider.notifier).update(proxySettings: null);
64+
} else {
65+
showDialog(
66+
context: context,
67+
builder: (context) => const ProxySettingsDialog(),
6968
);
70-
developer.log('Proxy settings updated', name: 'settings_page');
7169
}
7270
},
7371
),
74-
if (ref.watch(settingsProvider.select((settings) => settings.isProxyEnabled))) ...[
75-
ListTile(
76-
title: TextField(
77-
decoration: const InputDecoration(
78-
labelText: 'Proxy Host',
79-
hintText: 'e.g., localhost',
80-
),
81-
controller: TextEditingController(text: settings.proxyHost),
82-
onChanged: (value) {
83-
ref.read(settingsProvider.notifier).update(proxyHost: value);
84-
},
85-
),
86-
),
87-
ListTile(
88-
title: TextField(
89-
decoration: const InputDecoration(
90-
labelText: 'Proxy Port',
91-
hintText: 'e.g., 8080',
92-
),
93-
controller: TextEditingController(text: settings.proxyPort),
94-
onChanged: (value) {
95-
ref.read(settingsProvider.notifier).update(proxyPort: value);
96-
},
97-
),
98-
),
99-
ListTile(
100-
title: TextField(
101-
decoration: const InputDecoration(
102-
labelText: 'Username (Optional)',
103-
),
104-
controller: TextEditingController(text: settings.proxyUsername),
105-
onChanged: (value) {
106-
ref.read(settingsProvider.notifier).update(proxyUsername: value);
107-
},
108-
),
109-
),
110-
ListTile(
111-
title: TextField(
112-
decoration: const InputDecoration(
113-
labelText: 'Password (Optional)',
114-
),
115-
obscureText: true,
116-
controller: TextEditingController(text: settings.proxyPassword),
117-
onChanged: (value) {
118-
ref.read(settingsProvider.notifier).update(proxyPassword: value);
119-
},
120-
),
121-
),
122-
],
12372
SwitchListTile(
12473
hoverColor: kColorTransparent,
12574
title: const Text('Collection Pane Scrollbar Visiblity'),
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_riverpod/flutter_riverpod.dart';
3+
import 'package:apidash_core/models/models.dart';
4+
import 'package:apidash/providers/settings_providers.dart';
5+
6+
class ProxySettingsDialog extends ConsumerStatefulWidget {
7+
const ProxySettingsDialog({super.key});
8+
9+
@override
10+
ConsumerState<ProxySettingsDialog> createState() =>
11+
_ProxySettingsDialogState();
12+
}
13+
14+
class _ProxySettingsDialogState extends ConsumerState<ProxySettingsDialog> {
15+
late TextEditingController _hostController;
16+
late TextEditingController _portController;
17+
late TextEditingController _usernameController;
18+
late TextEditingController _passwordController;
19+
20+
@override
21+
void initState() {
22+
super.initState();
23+
final settings = ref.read(settingsProvider);
24+
final proxy = settings.proxySettings;
25+
_hostController = TextEditingController(text: proxy?.host ?? '');
26+
_portController = TextEditingController(text: proxy?.port ?? '');
27+
_usernameController = TextEditingController(text: proxy?.username ?? '');
28+
_passwordController = TextEditingController(text: proxy?.password ?? '');
29+
}
30+
31+
@override
32+
void dispose() {
33+
_hostController.dispose();
34+
_portController.dispose();
35+
_usernameController.dispose();
36+
_passwordController.dispose();
37+
super.dispose();
38+
}
39+
40+
void _saveSettings() {
41+
if (_hostController.text.isNotEmpty && _portController.text.isNotEmpty) {
42+
final newProxy = ProxySettings(
43+
host: _hostController.text,
44+
port: _portController.text,
45+
username: _usernameController.text.isEmpty ? null : _usernameController.text,
46+
password: _passwordController.text.isEmpty ? null : _passwordController.text,
47+
);
48+
ref.read(settingsProvider.notifier).update(proxySettings: newProxy);
49+
Navigator.of(context).pop();
50+
}
51+
else{
52+
ref.read(settingsProvider.notifier).update(proxySettings: null);
53+
}
54+
}
55+
56+
@override
57+
Widget build(BuildContext context) {
58+
return AlertDialog(
59+
title: const Text('Proxy Settings'),
60+
content: SingleChildScrollView(
61+
child: Column(
62+
mainAxisSize: MainAxisSize.min,
63+
children: [
64+
TextField(
65+
controller: _hostController,
66+
decoration: const InputDecoration(
67+
labelText: 'Proxy Host',
68+
hintText: 'e.g., localhost',
69+
),
70+
),
71+
const SizedBox(height: 8),
72+
TextField(
73+
controller: _portController,
74+
decoration: const InputDecoration(
75+
labelText: 'Proxy Port',
76+
hintText: 'e.g., 8080',
77+
),
78+
),
79+
const SizedBox(height: 8),
80+
TextField(
81+
controller: _usernameController,
82+
decoration: const InputDecoration(
83+
labelText: 'Username (Optional)',
84+
),
85+
),
86+
const SizedBox(height: 8),
87+
TextField(
88+
controller: _passwordController,
89+
decoration: const InputDecoration(
90+
labelText: 'Password (Optional)',
91+
),
92+
obscureText: true,
93+
),
94+
],
95+
),
96+
),
97+
actions: [
98+
TextButton(
99+
onPressed: () => Navigator.of(context).pop(),
100+
child: const Text('Cancel'),
101+
),
102+
TextButton(
103+
onPressed: _saveSettings,
104+
child: const Text('Save'),
105+
),
106+
],
107+
);
108+
}
109+
}

packages/apidash_core/lib/models/proxy_settings_model.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'package:freezed_annotation/freezed_annotation.dart';
2-
import 'package:json_annotation/json_annotation.dart';
32

43
part 'proxy_settings_model.freezed.dart';
54
part 'proxy_settings_model.g.dart';

0 commit comments

Comments
 (0)