✨ Crop image
This commit is contained in:
parent
b2a6ca7244
commit
5b9c92e4d3
@ -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
|
||||||
|
@ -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';
|
||||||
|
@ -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',
|
||||||
};
|
};
|
||||||
|
@ -303,4 +303,5 @@ const i18nSimplifiedChinese = {
|
|||||||
'themeColorLuka': '流音粉',
|
'themeColorLuka': '流音粉',
|
||||||
'themeColorApplied': '全局主题颜色已应用',
|
'themeColorApplied': '全局主题颜色已应用',
|
||||||
'attachmentSaved': '附件已保存到系统相册',
|
'attachmentSaved': '附件已保存到系统相册',
|
||||||
|
'cropImage': '裁剪图片',
|
||||||
};
|
};
|
||||||
|
@ -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(
|
||||||
|
@ -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" />
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user