image save

This commit is contained in:
wanghongenpin
2025-01-16 18:16:10 +08:00
parent 636a2b2361
commit b663b2d1ef
5 changed files with 66 additions and 17 deletions

View File

@@ -39,6 +39,8 @@ enum ContentType {
bool get isBinary {
return this == image || this == font || this == video;
}
bool get isImage => this == image;
}
class MediaType {

View File

@@ -157,7 +157,7 @@ class ProcessInfo {
icon = (await InstalledApps.getAppInfo(id)).icon;
}
if (Platform.operatingSystem == os || path.endsWith('.exe')) {
if ('windows' == os || path.endsWith('.exe')) {
icon = await _getWindowsIcon(path);
}

View File

@@ -17,10 +17,12 @@ import 'dart:convert';
import 'dart:io';
import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:file_picker/file_picker.dart';
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:image_pickers/image_pickers.dart';
import 'package:proxypin/network/components/manager/request_rewrite_manager.dart';
import 'package:proxypin/network/components/manager/rewrite_rule.dart';
import 'package:proxypin/network/http/content_type.dart';
@@ -111,6 +113,7 @@ class HttpBodyState extends State<HttpBodyWidget> {
if (tabIndex > 0 && tabIndex >= tabs.list.length) tabIndex = tabs.list.length - 1;
bodyKey.currentState?.changeState(widget.httpMessage, tabs.list[tabIndex]);
//TabBar
List<Widget> list = [
widget.inNewWindow ? const SizedBox() : titleWidget(),
const SizedBox(height: 3),
@@ -161,20 +164,25 @@ class HttpBodyState extends State<HttpBodyWidget> {
Widget titleWidget({inNewWindow = false}) {
var type = widget.httpMessage is HttpRequest ? "Request" : "Response";
bool isImage = widget.httpMessage?.contentType == ContentType.image;
var list = [
Text('$type Body', style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500)),
const SizedBox(width: 10),
IconButton(
icon: const Icon(Icons.copy, size: 18),
tooltip: localizations.copy,
onPressed: () {
var body = bodyKey.currentState?.body;
if (body == null) {
return;
}
Clipboard.setData(ClipboardData(text: body))
.then((value) => FlutterToastr.show(localizations.copied, context));
}),
isImage
? downloadImageButton()
: IconButton(
icon: Icon(Icons.copy, size: 18),
tooltip: localizations.copy,
onPressed: () {
var body = bodyKey.currentState?.body;
if (body == null) {
return;
}
Clipboard.setData(ClipboardData(text: body)).then((value) {
if (mounted) FlutterToastr.show(localizations.copied, context);
});
}),
];
if (!widget.hideRequestRewrite) {
@@ -201,7 +209,39 @@ class HttpBodyState extends State<HttpBodyWidget> {
return Wrap(crossAxisAlignment: WrapCrossAlignment.center, children: list);
}
//展示请求重写
///下载图片
Widget downloadImageButton() {
return IconButton(
icon: Icon(Icons.download, size: 20),
tooltip: localizations.saveImage,
onPressed: () async {
var body = bodyKey.currentState?.message?.body;
if (body == null) {
return;
}
var bytes = Uint8List.fromList(body);
if (Platforms.isMobile()) {
String? path = await ImagePickers.saveByteDataImageToGallery(bytes);
if (path != null && mounted) {
FlutterToastr.show(localizations.saveSuccess, context, duration: 2, rootNavigator: true);
}
return;
}
if (Platforms.isDesktop()) {
var fileName = "image_${DateTime.now().millisecondsSinceEpoch}.png";
String? path = (await FilePicker.platform.saveFile(fileName: fileName));
if (path == null) return;
await File(path).writeAsBytes(bytes);
if (mounted) {
FlutterToastr.show(localizations.saveSuccess, context, duration: 2);
}
}
});
}
///展示请求重写
showRequestRewrite() async {
HttpRequest? request;
if (widget.httpMessage == null) {
@@ -239,6 +279,7 @@ class HttpBodyState extends State<HttpBodyWidget> {
}
}
///打开新窗口
void openNew() async {
if (Platforms.isDesktop()) {
var size = MediaQuery.of(context).size;
@@ -374,7 +415,7 @@ class _BodyState extends State<_Body> {
return SelectableText(Uri.decodeFull(message!.bodyAsString), contextMenuBuilder: contextMenu);
}
if (type == ViewType.image) {
return Image.memory(Uint8List.fromList(message?.body ?? []), fit: BoxFit.scaleDown);
return Center(child: Image.memory(Uint8List.fromList(message?.body ?? []), fit: BoxFit.scaleDown));
}
if (type == ViewType.video) {
return const Center(child: Text("video not support preview"));

View File

@@ -125,8 +125,14 @@ class RequestSequenceState extends State<RequestSequence> with AutomaticKeepAliv
return futureWidget(
processInfo.getIcon(),
(data) =>
data.isEmpty ? const SizedBox() : Image.memory(data, width: 23, height: Platform.isWindows ? 16 : null));
(data) => data.isEmpty
? const SizedBox()
: Image.memory(
data,
width: 23,
height: Platform.isWindows ? 16 : null,
errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) => const SizedBox(),
));
}
///高亮处理

View File

@@ -199,7 +199,7 @@ class RewriteReplaceState extends State<DesktopRewriteReplace> {
});
},
),
const SizedBox(width: 10),
const SizedBox(width: 15),
Text(localizations.enable),
const SizedBox(width: 10),
SwitchWidget(