Crop image

This commit is contained in:
LittleSheep 2024-08-01 23:44:07 +08:00
parent b2a6ca7244
commit 5b9c92e4d3
6 changed files with 74 additions and 18 deletions

View File

@ -70,6 +70,12 @@
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data <meta-data

View File

@ -1,7 +1,7 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
abstract class ServiceFinder { abstract class ServiceFinder {
static const bool devFlag = true; static const bool devFlag = false;
static const String dealerUrl = static const String dealerUrl =
devFlag ? 'http://localhost:8442' : 'https://api.sn.solsynth.dev'; devFlag ? 'http://localhost:8442' : 'https://api.sn.solsynth.dev';

View File

@ -326,4 +326,5 @@ const i18nEnglish = {
'themeColorLuka': 'Luka Pink', 'themeColorLuka': 'Luka Pink',
'themeColorApplied': 'Global theme color has been applied.', 'themeColorApplied': 'Global theme color has been applied.',
'attachmentSaved': 'Attachment saved to your system album.', 'attachmentSaved': 'Attachment saved to your system album.',
'cropImage': 'Crop Image',
}; };

View File

@ -303,4 +303,5 @@ const i18nSimplifiedChinese = {
'themeColorLuka': '流音粉', 'themeColorLuka': '流音粉',
'themeColorApplied': '全局主题颜色已应用', 'themeColorApplied': '全局主题颜色已应用',
'attachmentSaved': '附件已保存到系统相册', 'attachmentSaved': '附件已保存到系统相册',
'cropImage': '裁剪图片',
}; };

View File

@ -8,9 +8,10 @@ import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_animate/flutter_animate.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:pasteboard/pasteboard.dart'; import 'package:pasteboard/pasteboard.dart';
import 'package:path/path.dart' show basename; import 'package:path/path.dart' show basename, extension;
import 'package:solian/exts.dart'; import 'package:solian/exts.dart';
import 'package:solian/models/attachment.dart'; import 'package:solian/models/attachment.dart';
import 'package:solian/platform.dart'; import 'package:solian/platform.dart';
@ -203,6 +204,31 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
); );
} }
Future<void> _cropAttachment(int queueIndex) async {
final task = _uploadController.queueOfUpload[queueIndex];
CroppedFile? croppedFile = await ImageCropper().cropImage(
sourcePath: task.file.path,
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'cropImage'.tr,
toolbarColor: Colors.deepOrange,
toolbarWidgetColor: Colors.white,
aspectRatioPresets: CropAspectRatioPreset.values,
),
IOSUiSettings(
title: 'cropImage'.tr,
aspectRatioPresets: CropAspectRatioPreset.values,
),
WebUiSettings(
context: context,
),
],
);
if (croppedFile == null) return;
_uploadController.queueOfUpload[queueIndex].file = File(croppedFile.path);
_uploadController.queueOfUpload.refresh();
}
Future<void> _deleteAttachment(Attachment element) async { Future<void> _deleteAttachment(Attachment element) async {
setState(() => _isBusy = true); setState(() => _isBusy = true);
try { try {
@ -216,6 +242,9 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
} }
Widget _buildQueueEntry(AttachmentUploadTask element, int index) { Widget _buildQueueEntry(AttachmentUploadTask element, int index) {
final extName = extension(element.file.path).substring(1);
final canBeCrop = ['png', 'jpg', 'jpeg', 'gif'].contains(extName);
return Container( return Container(
padding: const EdgeInsets.only(left: 16, right: 8, bottom: 16), padding: const EdgeInsets.only(left: 16, right: 8, bottom: 16),
child: Card( child: Card(
@ -269,23 +298,38 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
child: Icon(Icons.check), child: Icon(Icons.check),
), ),
), ),
if (!element.isCompleted && canBeCrop)
Obx(
() => IconButton(
color: Colors.teal,
icon: const Icon(Icons.crop),
visualDensity: const VisualDensity(horizontal: -4),
onPressed: _uploadController.isUploading.value
? null
: () {
_cropAttachment(index);
},
),
),
if (!element.isCompleted && !element.isUploading) if (!element.isCompleted && !element.isUploading)
IconButton( Obx(
color: Colors.green, () => IconButton(
icon: const Icon(Icons.play_arrow), color: Colors.green,
visualDensity: const VisualDensity(horizontal: -4), icon: const Icon(Icons.play_arrow),
onPressed: _uploadController.isUploading.value visualDensity: const VisualDensity(horizontal: -4),
? null onPressed: _uploadController.isUploading.value
: () { ? null
_uploadController : () {
.performSingleTask(index) _uploadController
.then((r) { .performSingleTask(index)
widget.onAdd(r.id); .then((r) {
if (mounted) { widget.onAdd(r.id);
setState(() => _attachments.add(r)); if (mounted) {
} setState(() => _attachments.add(r));
}); }
}, });
},
),
), ),
if (!element.isCompleted && !element.isUploading) if (!element.isCompleted && !element.isUploading)
IconButton( IconButton(

View File

@ -26,6 +26,10 @@
<meta name="apple-mobile-web-app-title" content="solian" /> <meta name="apple-mobile-web-app-title" content="solian" />
<link rel="apple-touch-icon" href="icons/Icon-192.png" /> <link rel="apple-touch-icon" href="icons/Icon-192.png" />
<!-- Cropper.js -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.6.2/cropper.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.6.2/cropper.min.js"></script>
<!-- Favicon --> <!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png" /> <link rel="icon" type="image/png" href="favicon.png" />