Optimize request pop-up menu UI

This commit is contained in:
wanghongenpin
2024-10-20 03:03:09 +08:00
parent 6a63549311
commit a01b03d97b
12 changed files with 302 additions and 192 deletions

View File

@@ -72,8 +72,8 @@
"type": "Type",
"enable": "Enable",
"example": "Example: ",
"responseHeader": "Response Header",
"requestHeader": "Request Header",
"responseHeader": "Headers",
"requestHeader": "Headers",
"requestLine": "Request Line",
"requestMethod": "Request Method",
"param": "Param",
@@ -124,6 +124,7 @@
"deleteWhitelist": "Delete Proxy Whitelist",
"domainListSubtitle": "Last Request Time: {time}, Count: {count}",
"selectAction": "Select action",
"copy": "Copy",
"copyHost": "Copy Host",
"copyUrl": "Copy URL",

View File

@@ -124,12 +124,13 @@
"deleteWhitelist": "删除代理白名单",
"domainListSubtitle": "最后请求时间: {time}, 次数: {count}",
"selectAction": "选择操作",
"copy": "复制",
"copyHost": "复制域名",
"copyUrl": "复制URL",
"copyRequestResponse": "复制 请求和响应",
"copyCurl": "复制 cURL 请求",
"copyAsPythonRequests": "复制 Python Requests 请求",
"copyCurl": "复制 cURL",
"copyAsPythonRequests": "复制 Python Requests",
"delete": "删除",
"rename": "重命名",
"repeat": "重放",
@@ -153,7 +154,7 @@
"keyword": "关键词",
"keywordSearchScope": "关键词搜索范围: ",
"favorite": "收藏请求",
"favorite": "收藏",
"deleteFavorite": "删除收藏",
"emptyFavorite": "暂无收藏",
"deleteFavoriteSuccess": "已删除收藏",

View File

@@ -2,14 +2,10 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_js/quickjs/ffi.dart';
import 'package:flutter_toastr/flutter_toastr.dart';
import 'package:network_proxy/network/bin/server.dart';
import 'package:network_proxy/network/components/script_manager.dart';
import 'package:network_proxy/network/http/http.dart';
import 'package:network_proxy/ui/component/utils.dart';
import 'package:network_proxy/ui/mobile/request/request_editor.dart';
import 'package:network_proxy/ui/mobile/setting/script.dart';
import 'package:network_proxy/utils/curl.dart';
import 'package:share_plus/share_plus.dart';
@@ -25,67 +21,46 @@ class ShareWidget extends StatelessWidget {
Widget build(BuildContext context) {
AppLocalizations localizations = AppLocalizations.of(context)!;
return IconButton(
icon: const Icon(Icons.share),
onPressed: () {
showMenu(context: context, position: menuPosition(context), items: [
PopupMenuItem(
child: Text(localizations.shareUrl),
return PopupMenuButton(
icon: const Icon(Icons.share, size: 24),
offset: const Offset(0, 30),
itemBuilder: (BuildContext context) {
return [
PopupMenuItem(
child: Text(localizations.shareUrl),
onTap: () {
if (request == null) {
FlutterToastr.show("Request is empty", context);
return;
}
Share.share(request!.requestUrl, subject: localizations.proxyPinSoftware);
},
),
PopupMenuItem(
padding: const EdgeInsets.only(left: 10),
child: Text(localizations.shareRequestResponse),
onTap: () {
if (request == null) {
FlutterToastr.show("Request is empty", context);
return;
}
Share.share(request!.requestUrl, subject: localizations.proxyPinSoftware);
},
),
PopupMenuItem(
child: Text(localizations.shareRequestResponse),
onTap: () {
if (request == null) {
FlutterToastr.show("Request is empty", context);
return;
}
var file = XFile.fromData(utf8.encode(copyRequest(request!, response)),
name: localizations.captureDetail, mimeType: "txt");
Share.shareXFiles([file], fileNameOverrides: ['request.txt'], text: localizations.proxyPinSoftware);
}),
PopupMenuItem(
child: Text(localizations.shareCurl),
onTap: () {
if (request == null) {
return;
}
var text = curlRequest(request!);
var file = XFile.fromData(utf8.encode(text), name: "cURL.txt", mimeType: "txt");
Share.shareXFiles([file], fileNameOverrides: ["cURL.txt"], text: localizations.proxyPinSoftware);
}),
PopupMenuItem(
child: Text(localizations.requestEdit),
onTap: () {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => MobileRequestEditor(request: request, proxyServer: proxyServer)));
});
}),
PopupMenuItem(
child: Text(localizations.script),
onTap: () {
WidgetsBinding.instance.addPostFrameCallback((_) async {
var scriptManager = await ScriptManager.instance;
var url = '${request?.remoteDomain()}${request?.path()}';
var scriptItem = (scriptManager).list.firstWhereOrNull((it) => it.url == url);
String? script = scriptItem == null ? null : await scriptManager.getScript(scriptItem);
if (!context.mounted) return;
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
ScriptEdit(scriptItem: scriptItem, script: script, url: scriptItem?.url ?? url)));
});
}),
]);
});
var file = XFile.fromData(utf8.encode(copyRequest(request!, response)),
name: localizations.captureDetail, mimeType: "txt");
Share.shareXFiles([file], fileNameOverrides: ['request.txt'], text: localizations.proxyPinSoftware);
}),
PopupMenuItem(
padding: const EdgeInsets.only(left: 10),
child: Text(localizations.shareCurl),
onTap: () {
if (request == null) {
return;
}
var text = curlRequest(request!);
var file = XFile.fromData(utf8.encode(text), name: "cURL.txt", mimeType: "txt");
Share.shareXFiles([file], fileNameOverrides: ["cURL.txt"], text: localizations.proxyPinSoftware);
}),
];
},
);
}
}

View File

@@ -90,7 +90,7 @@ class _ToolboxState extends State<Toolbox> {
onTap: () => encodeWindow(EncoderType.base64, context),
child: Container(
padding: const EdgeInsets.all(10),
child: const Column(children: [Icon(Icons.currency_bitcoin), SizedBox(height: 3), Text('Base64')]),
child: const Column(children: [Icon(Icons.format_bold), SizedBox(height: 3), Text('Base64')]),
)),
const SizedBox(width: 15),
InkWell(

View File

@@ -10,6 +10,7 @@ class CustomPopupMenuItem<T> extends PopupMenuItem<T> {
super.height,
super.value,
super.enabled,
super.padding,
required Widget super.child,
this.color,
});
@@ -30,6 +31,28 @@ class _CustomPopupMenuItemState<T> extends PopupMenuItemState<T, CustomPopupMenu
}
}
class PopupMenuContainer extends PopupMenuEntry {
final Widget child;
@override
final double height;
const PopupMenuContainer({super.key, required this.child, this.height = 40});
@override
bool represents(value) => false;
@override
State<StatefulWidget> createState() => _PopupMenuContainerState();
}
class _PopupMenuContainerState extends State<PopupMenuContainer> {
@override
Widget build(BuildContext context) {
return widget.child;
}
}
class SwitchWidget extends StatefulWidget {
final String? title;
final String? subtitle;

View File

@@ -14,16 +14,24 @@
* limitations under the License.
*/
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_toastr/flutter_toastr.dart';
import 'package:network_proxy/network/bin/server.dart';
import 'package:network_proxy/network/components/script_manager.dart';
import 'package:network_proxy/network/http/http.dart';
import 'package:network_proxy/network/http/websocket.dart';
import 'package:network_proxy/storage/favorites.dart';
import 'package:network_proxy/ui/component/share.dart';
import 'package:network_proxy/ui/component/state_component.dart';
import 'package:network_proxy/ui/component/utils.dart';
import 'package:network_proxy/ui/component/widgets.dart';
import 'package:network_proxy/ui/configuration.dart';
import 'package:network_proxy/ui/mobile/request/request_editor.dart';
import 'package:network_proxy/ui/mobile/setting/script.dart';
import 'package:network_proxy/utils/lang.dart';
import 'package:network_proxy/utils/platform.dart';
import 'package:network_proxy/utils/python.dart';
import 'body.dart';
@@ -114,7 +122,61 @@ class NetworkTabState extends State<NetworkTabController> with SingleTickerProvi
bottom: tabBar,
actions: [
ShareWidget(
proxyServer: widget.proxyServer, request: widget.request.get(), response: widget.response.get())
proxyServer: widget.proxyServer, request: widget.request.get(), response: widget.response.get()),
const SizedBox(width: 3),
PopupMenuButton(
offset: const Offset(0, 30),
padding: const EdgeInsets.all(0),
itemBuilder: (context) => [
PopupMenuItem(
child: Text(localizations.favorite),
onTap: () {
var request = widget.request.get();
if (request == null) return;
FavoriteStorage.addFavorite(request);
FlutterToastr.show(localizations.addSuccess, context);
}),
PopupMenuItem(
child: Text(localizations.requestEdit),
onTap: () {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => MobileRequestEditor(
request: widget.request.get(), proxyServer: widget.proxyServer)));
});
}),
PopupMenuItem(
child: Text(localizations.script),
onTap: () {
WidgetsBinding.instance.addPostFrameCallback((_) async {
var scriptManager = await ScriptManager.instance;
var request = widget.request.get();
var url = '${request?.remoteDomain()}${request?.path()}';
var scriptItem = (scriptManager).list.firstWhereOrNull((it) => it.url == url);
String? script = scriptItem == null ? null : await scriptManager.getScript(scriptItem);
if (!context.mounted) return;
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ScriptEdit(
scriptItem: scriptItem, script: script, url: scriptItem?.url ?? url)));
});
}),
CustomPopupMenuItem(
padding: const EdgeInsets.only(left: 10),
child: Text(localizations.copyAsPythonRequests),
onTap: () {
var request = widget.request.get();
if (request == null) return;
var text = copyAsPythonRequests(request);
Clipboard.setData(ClipboardData(text: text));
FlutterToastr.show(localizations.copied, context);
})
],
child: const SizedBox(height: 38, width: 38, child: Icon(Icons.more_vert, size: 28))),
const SizedBox(width: 10),
],
);

View File

@@ -619,7 +619,7 @@ class _RuleAddDialogState extends State<RuleAddDialog> {
decoration: InputDecoration(
hintText: hint,
hintStyle: TextStyle(color: Colors.grey.shade500, fontSize: 14),
contentPadding: const EdgeInsets.all(10),
contentPadding: const EdgeInsets.symmetric(horizontal: 5, vertical: 10),
errorStyle: const TextStyle(height: 0, fontSize: 0),
focusedBorder: focusedBorder(),
isDense: true,

View File

@@ -102,6 +102,11 @@ class _MePageState extends State<MePage> {
navigator(context, MobileRequestRewrite(requestRewrites: requestRewrites));
}
}),
ListTile(
title: Text(localizations.script),
leading: Icon(Icons.javascript_outlined, color: color),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () => navigator(context, const MobileScript())),
ListTile(
title: Text(localizations.requestBlock),
leading: Icon(Icons.block_flipped, color: color),
@@ -112,11 +117,6 @@ class _MePageState extends State<MePage> {
navigator(context, MobileRequestBlock(requestBlockManager: requestBlockManager));
}
}),
ListTile(
title: Text(localizations.script),
leading: Icon(Icons.code, color: color),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () => navigator(context, const MobileScript())),
ListTile(
title: Text(localizations.setting),
leading: Icon(Icons.settings_outlined, color: color),

View File

@@ -32,7 +32,6 @@ import 'package:network_proxy/ui/mobile/request/repeat.dart';
import 'package:network_proxy/ui/mobile/request/request_editor.dart';
import 'package:network_proxy/utils/curl.dart';
import 'package:network_proxy/utils/lang.dart';
import 'package:network_proxy/utils/python.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// 收藏列表页面
@@ -164,8 +163,6 @@ class _FavoriteItemState extends State<_FavoriteItem> {
const Divider(thickness: 0.5, height: 5),
menuItem(localizations.copyCurl, () => curlRequest(request)),
const Divider(thickness: 0.5, height: 5),
menuItem(localizations.copyAsPythonRequests, () => copyAsPythonRequests(request)),
const Divider(thickness: 0.5, height: 5),
TextButton(
child: SizedBox(width: double.infinity, child: Text(localizations.rename, textAlign: TextAlign.center)),
onPressed: () {

View File

@@ -27,6 +27,7 @@ import 'package:network_proxy/network/http_client.dart';
import 'package:network_proxy/network/util/cache.dart';
import 'package:network_proxy/storage/favorites.dart';
import 'package:network_proxy/ui/component/utils.dart';
import 'package:network_proxy/ui/component/widgets.dart';
import 'package:network_proxy/ui/content/panel.dart';
import 'package:network_proxy/ui/mobile/request/repeat.dart';
import 'package:network_proxy/ui/mobile/request/request_editor.dart';
@@ -94,33 +95,36 @@ class RequestRowState extends State<RequestRow> {
var highlightColor = KeywordHighlight.getHighlightColor(url);
return ListTile(
visualDensity: const VisualDensity(vertical: -4),
minLeadingWidth: 5,
selected: selected,
textColor: highlightColor,
selectedColor: highlightColor,
leading: appIcon(),
title: Text(title, overflow: TextOverflow.ellipsis, maxLines: 2, style: const TextStyle(fontSize: 14)),
subtitle: Text.rich(
maxLines: 1,
TextSpan(children: [
TextSpan(text: '#${widget.index} ', style: const TextStyle(fontSize: 11, color: Colors.teal)),
TextSpan(text: subTitle, style: const TextStyle(fontSize: 11, color: Colors.grey)),
])),
trailing: getIcon(response),
contentPadding:
Platform.isIOS ? const EdgeInsets.symmetric(horizontal: 8) : const EdgeInsets.only(left: 3, right: 5),
onLongPress: menu,
onTap: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return NetworkTabController(
proxyServer: widget.proxyServer,
httpRequest: request,
httpResponse: response,
title: Text(localizations.captureDetail, style: const TextStyle(fontSize: 16)));
}));
});
return GestureDetector(
onLongPressStart: menu,
child: ListTile(
visualDensity: const VisualDensity(vertical: -4),
minLeadingWidth: 5,
selected: selected,
textColor: highlightColor,
selectedColor: highlightColor,
leading: appIcon(),
title: Text(title, overflow: TextOverflow.ellipsis, maxLines: 2, style: const TextStyle(fontSize: 14)),
subtitle: Text.rich(
maxLines: 1,
TextSpan(children: [
TextSpan(text: '#${widget.index} ', style: const TextStyle(fontSize: 11, color: Colors.teal)),
TextSpan(text: subTitle, style: const TextStyle(fontSize: 11, color: Colors.grey)),
])),
trailing: getIcon(response),
contentPadding:
Platform.isIOS ? const EdgeInsets.symmetric(horizontal: 8) : const EdgeInsets.only(left: 3, right: 5),
onTap: () {
Navigator.of(this.context).push(MaterialPageRoute(builder: (context) {
return NetworkTabController(
proxyServer: widget.proxyServer,
httpRequest: request,
httpResponse: response,
title: Text(localizations.captureDetail, style: const TextStyle(fontSize: 16)));
}));
},
));
}
Widget? appIcon() {
@@ -149,78 +153,125 @@ class RequestRowState extends State<RequestRow> {
}
///菜单
menu() {
menu(details) {
setState(() {
selected = true;
});
showModalBottomSheet(
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(10))),
context: context,
isScrollControlled: true,
enableDrag: true,
builder: (ctx) {
return Wrap(alignment: WrapAlignment.center, children: [
menuCopyItem(localizations.copyUrl, () => widget.request.requestUrl),
const Divider(thickness: 0.5, height: 5),
menuCopyItem(localizations.copyCurl, () => curlRequest(widget.request)),
const Divider(thickness: 0.5, height: 5),
TextButton(
child: SizedBox(width: double.infinity, child: Text(localizations.repeat, textAlign: TextAlign.center)),
onPressed: () {
onRepeat(widget.request);
Navigator.maybePop(context);
}),
const Divider(thickness: 0.5, height: 5),
TextButton(
child: SizedBox(
width: double.infinity, child: Text(localizations.customRepeat, textAlign: TextAlign.center)),
onPressed: () => showCustomRepeat(widget.request)),
const Divider(thickness: 0.5, height: 5),
TextButton(
child:
SizedBox(width: double.infinity, child: Text(localizations.editRequest, textAlign: TextAlign.center)),
onPressed: () {
Navigator.maybePop(context);
var pageRoute = MaterialPageRoute(
builder: (context) =>
MobileRequestEditor(request: widget.request, proxyServer: widget.proxyServer));
if (mounted) {
Navigator.push(context, pageRoute);
} else {
NavigatorHelper.push(pageRoute);
}
}),
const Divider(thickness: 0.5, height: 5),
TextButton(
child: SizedBox(width: double.infinity, child: Text(localizations.favorite, textAlign: TextAlign.center)),
onPressed: () {
FavoriteStorage.addFavorite(widget.request);
FlutterToastr.show(localizations.addSuccess, context);
Navigator.maybePop(context);
}),
const Divider(thickness: 0.5, height: 5),
TextButton(
child: SizedBox(width: double.infinity, child: Text(localizations.delete, textAlign: TextAlign.center)),
onPressed: () {
widget.onRemove?.call(request);
FlutterToastr.show(localizations.deleteSuccess, context);
Navigator.maybePop(context);
}),
Container(color: Theme.of(context).hoverColor, height: 8),
TextButton(
child: Container(
height: 45,
width: double.infinity,
padding: const EdgeInsets.only(top: 10),
child: Text(localizations.cancel, textAlign: TextAlign.center)),
onPressed: () {
Navigator.maybePop(context);
},
),
]);
},
).then((value) {
var globalPosition = details.globalPosition;
MediaQueryData mediaQuery = MediaQuery.of(context);
var position = RelativeRect.fromLTRB(globalPosition.dx, globalPosition.dy, globalPosition.dx, globalPosition.dy);
// Trigger haptic feedback
HapticFeedback.mediumImpact();
showMenu(
context: context,
constraints: BoxConstraints(maxWidth: mediaQuery.size.width * 0.88),
position: position,
items: [
//复制url
PopupMenuContainer(
child: Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.only(left: 20, top: 5),
child: Text(localizations.selectAction, style: Theme.of(context).textTheme.bodyLarge)),
),
//copy
menuItem(
left: button(
onPressed: () {
Clipboard.setData(ClipboardData(text: request.requestUrl)).then((value) {
if (mounted) {
FlutterToastr.show(localizations.copied, context);
Navigator.maybePop(context);
}
});
},
label: localizations.copyUrl,
icon: Icons.link,
iconSize: 22),
right: button(
onPressed: () {
Clipboard.setData(ClipboardData(text: curlRequest(request))).then((value) {
if (mounted) {
FlutterToastr.show(localizations.copied, context);
Navigator.maybePop(context);
}
});
},
label: localizations.copyCurl,
icon: Icons.code),
),
//repeat
menuItem(
left: button(
onPressed: () {
onRepeat(request);
Navigator.maybePop(context);
},
label: localizations.repeat,
icon: Icons.repeat_one),
right: button(
onPressed: () => showCustomRepeat(request), label: localizations.customRepeat, icon: Icons.repeat),
),
//favorite and edit
menuItem(
left: button(
onPressed: () {
FavoriteStorage.addFavorite(widget.request);
FlutterToastr.show(localizations.addSuccess, context);
Navigator.maybePop(context);
},
label: localizations.favorite,
icon: Icons.favorite_outline),
right: button(
onPressed: () {
Navigator.pop(context);
var pageRoute = MaterialPageRoute(
builder: (context) =>
MobileRequestEditor(request: widget.request, proxyServer: widget.proxyServer));
if (mounted) {
Navigator.push(context, pageRoute);
} else {
NavigatorHelper.push(pageRoute);
}
},
label: localizations.editRequest,
icon: Icons.edit_outlined),
),
// menuItem(
// left: button(
// onPressed: () {}, label: localizations.script, icon: Icons.javascript_outlined, iconSize: 24),
// right: button(onPressed: () {}, label: localizations.requestRewrite, icon: Icons.replay_outlined),
// ),
// menuItem(
// left: TextButton.icon(
// onPressed: () {},
// label: Text(localizations.highlight),
// icon: const Icon(Icons.highlight_outlined, size: 20)),
// right: TextButton.icon(
// onPressed: () {},
// label: Text(localizations.requestRewrite),
// icon: const Icon(Icons.highlight_remove, size: 20)),
// ),
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
button(
onPressed: () {
widget.onRemove?.call(request);
FlutterToastr.show(localizations.deleteSuccess, context);
Navigator.maybePop(context);
},
label: localizations.delete,
icon: Icons.delete_outline),
SizedBox(width: 15),
]),
],
)),
]).then((value) {
selected = false;
if (mounted) setState(() {});
});
@@ -228,7 +279,7 @@ class RequestRowState extends State<RequestRow> {
//显示高级重发
showCustomRepeat(HttpRequest request) {
Navigator.maybePop(context);
Navigator.pop(context);
var pageRoute = MaterialPageRoute(
builder: (context) => futureWidget(SharedPreferences.getInstance(),
(prefs) => MobileCustomRepeat(onRepeat: () => onRepeat(request), prefs: prefs)));
@@ -249,16 +300,18 @@ class RequestRowState extends State<RequestRow> {
}
}
Widget menuCopyItem(String title, String Function() callback) {
return TextButton(
child: SizedBox(width: double.infinity, child: Text(title, textAlign: TextAlign.center)),
onPressed: () {
Clipboard.setData(ClipboardData(text: callback.call())).then((value) {
if (mounted) {
FlutterToastr.show(localizations.copied, context);
Navigator.maybePop(context);
}
});
});
Widget button({required String label, required IconData icon, required Function() onPressed, double iconSize = 20}) {
var style = Theme.of(context).textTheme.bodyMedium;
return TextButton.icon(
onPressed: onPressed, label: Text(label, style: style), icon: Icon(icon, size: iconSize, color: style?.color));
}
Widget menuItem({required Widget left, required Widget right}) {
return Row(
children: [
SizedBox(width: 130, child: Align(alignment: Alignment.centerLeft, child: left)),
Expanded(child: Align(alignment: Alignment.centerLeft, child: right))
],
);
}
}

View File

@@ -494,7 +494,7 @@ class _RewriteRuleState extends State<RewriteRule> {
child: ListView(children: <Widget>[
Row(children: [
SizedBox(
width: 58,
width: 60,
child: Text('${localizations.enable}:',
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500))),
SwitchWidget(value: rule.enabled, onChanged: (val) => rule.enabled = val, scale: 0.8)
@@ -504,7 +504,7 @@ class _RewriteRuleState extends State<RewriteRule> {
required: true, keyboardType: TextInputType.url),
Row(children: [
SizedBox(
width: 58,
width: 60,
child: Text('${localizations.action}:',
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500))),
SizedBox(
@@ -546,7 +546,7 @@ class _RewriteRuleState extends State<RewriteRule> {
Widget textField(String label, TextEditingController controller, String hint,
{bool required = false, TextInputType? keyboardType, FormFieldSetter<String>? onSaved}) {
return Row(children: [
SizedBox(width: 58, child: Text(label, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500))),
SizedBox(width: 60, child: Text(label, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500))),
Expanded(
child: TextFormField(
controller: controller,
@@ -556,7 +556,7 @@ class _RewriteRuleState extends State<RewriteRule> {
decoration: InputDecoration(
hintText: hint,
hintStyle: TextStyle(color: Colors.grey.shade500),
contentPadding: const EdgeInsets.all(10),
contentPadding: const EdgeInsets.only(),
errorStyle: const TextStyle(height: 0, fontSize: 0),
),
))

View File

@@ -347,9 +347,7 @@ class RewriteReplaceState extends State<MobileRewriteReplace> {
Widget statusCodeEdit() {
var rewriteItem = items.firstWhere((item) => item.type == RewriteType.replaceResponseStatus);
return Container(
padding: const EdgeInsets.all(10),
child: Column(children: [
return Column(children: [
Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
Text(localizations.statusCode),
const SizedBox(width: 10),
@@ -379,7 +377,7 @@ class RewriteReplaceState extends State<MobileRewriteReplace> {
])),
const SizedBox(width: 10),
])
]));
]);
}
InputDecoration decoration(String label, {String? hintText}) {