D1APversionP-74 image cropper final

This commit is contained in:
MohammadTaha Basiri 2022-02-22 19:27:53 +03:30
parent 79645b2074
commit b8dfbc2345
9 changed files with 53 additions and 254 deletions

View File

@ -36,6 +36,10 @@
<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 -->
</application> </application>

View File

@ -9,6 +9,9 @@ PODS:
- FMDB (2.7.5): - FMDB (2.7.5):
- FMDB/standard (= 2.7.5) - FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5) - FMDB/standard (2.7.5)
- image_cropper (0.0.4):
- Flutter
- TOCropViewController (~> 2.6.1)
- image_picker (0.0.1): - image_picker (0.0.1):
- Flutter - Flutter
- just_audio (0.0.1): - just_audio (0.0.1):
@ -20,6 +23,7 @@ PODS:
- sqflite (0.0.2): - sqflite (0.0.2):
- Flutter - Flutter
- FMDB (>= 2.7.5) - FMDB (>= 2.7.5)
- TOCropViewController (2.6.1)
- url_launcher_ios (0.0.1): - url_launcher_ios (0.0.1):
- Flutter - Flutter
@ -28,6 +32,7 @@ DEPENDENCIES:
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- flutter_vibrate (from `.symlinks/plugins/flutter_vibrate/ios`) - flutter_vibrate (from `.symlinks/plugins/flutter_vibrate/ios`)
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
- image_picker (from `.symlinks/plugins/image_picker/ios`) - image_picker (from `.symlinks/plugins/image_picker/ios`)
- just_audio (from `.symlinks/plugins/just_audio/ios`) - just_audio (from `.symlinks/plugins/just_audio/ios`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
@ -38,6 +43,7 @@ DEPENDENCIES:
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- FMDB - FMDB
- TOCropViewController
EXTERNAL SOURCES: EXTERNAL SOURCES:
audio_session: audio_session:
@ -48,6 +54,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_secure_storage/ios" :path: ".symlinks/plugins/flutter_secure_storage/ios"
flutter_vibrate: flutter_vibrate:
:path: ".symlinks/plugins/flutter_vibrate/ios" :path: ".symlinks/plugins/flutter_vibrate/ios"
image_cropper:
:path: ".symlinks/plugins/image_cropper/ios"
image_picker: image_picker:
:path: ".symlinks/plugins/image_picker/ios" :path: ".symlinks/plugins/image_picker/ios"
just_audio: just_audio:
@ -67,11 +75,13 @@ SPEC CHECKSUMS:
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
flutter_vibrate: 9f4c2ab57008965f78969472367c329dd77eb801 flutter_vibrate: 9f4c2ab57008965f78969472367c329dd77eb801
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98
image_picker: 9aa50e1d8cdacdbed739e925b7eea16d014367e6 image_picker: 9aa50e1d8cdacdbed739e925b7eea16d014367e6
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
path_provider_ios: 7d7ce634493af4477d156294792024ec3485acd5 path_provider_ios: 7d7ce634493af4477d156294792024ec3485acd5
record: 7ee2393532f8553bbb09fa19e95478323b7c0a99 record: 7ee2393532f8553bbb09fa19e95478323b7c0a99
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
url_launcher_ios: 02f1989d4e14e998335b02b67a7590fa34f971af url_launcher_ios: 02f1989d4e14e998335b02b67a7590fa34f971af
PODFILE CHECKSUM: a75497545d4391e2d394c3668e20cfb1c2bbd4aa PODFILE CHECKSUM: a75497545d4391e2d394c3668e20cfb1c2bbd4aa

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/enums.dart'; import 'package:didvan/models/enums.dart';
@ -5,15 +7,16 @@ import 'package:didvan/models/view/action_sheet_data.dart';
import 'package:didvan/models/view/alert_data.dart'; import 'package:didvan/models/view/alert_data.dart';
import 'package:didvan/pages/home/widgets/menu_item.dart'; import 'package:didvan/pages/home/widgets/menu_item.dart';
import 'package:didvan/providers/user_provider.dart'; import 'package:didvan/providers/user_provider.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/media/media.dart'; import 'package:didvan/services/media/media.dart';
import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/widgets/didvan/divider.dart'; import 'package:didvan/widgets/didvan/divider.dart';
import 'package:didvan/widgets/didvan/text.dart'; import 'package:didvan/widgets/didvan/text.dart';
import 'package:didvan/widgets/skeleton_image.dart'; import 'package:didvan/widgets/skeleton_image.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:image_cropper/image_cropper.dart';
class ProfilePhoto extends StatefulWidget { class ProfilePhoto extends StatefulWidget {
const ProfilePhoto({Key? key}) : super(key: key); const ProfilePhoto({Key? key}) : super(key: key);
@ -135,27 +138,31 @@ class _ProfilePhotoState extends State<ProfilePhoto> {
return; return;
} }
final pickedFile = await MediaService.pickImage(source: source); final pickedFile = await MediaService.pickImage(source: source);
if (pickedFile != null) { File? file;
ActionSheetUtils.showLogoLoadingIndicator(); if (pickedFile != null && !kIsWeb) {
final bytes = await pickedFile.readAsBytes(); file = await ImageCropper().cropImage(
ActionSheetUtils.pop(); sourcePath: pickedFile.path,
Navigator.of(context).pushNamed( aspectRatio: const CropAspectRatio(ratioX: 1, ratioY: 1),
Routes.imageCropper, iosUiSettings: const IOSUiSettings(
arguments: { title: 'برش تصویر',
'bytes': bytes, doneButtonTitle: 'تایید',
'onCropped': () async { cancelButtonTitle: 'بازگشت',
final result = await state.setProfilePhoto(pickedFile); ),
ActionSheetUtils.showAlert( androidUiSettings: const AndroidUiSettings(toolbarTitle: 'برش تصویر'),
AlertData( compressQuality: 70,
message: result
? 'تصویر پروفایل بارگذاری شد.'
: 'بارگذاری تصویر موفقیت آمیز نبود.',
aLertType: result ? ALertType.success : ALertType.error,
),
);
}
},
); );
if (file == null) return;
} }
if (pickedFile == null) return;
final uploadFile = kIsWeb ? pickedFile : file;
final result = await state.setProfilePhoto(uploadFile);
ActionSheetUtils.showAlert(
AlertData(
message: result
? 'تصویر پروفایل بارگذاری شد.'
: 'بارگذاری تصویر موفقیت آمیز نبود.',
aLertType: result ? ALertType.success : ALertType.error,
),
);
} }
} }

View File

@ -64,7 +64,7 @@ class _SplashState extends State<Splash> {
SpinKitSpinningLines( SpinKitSpinningLines(
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
if (_errorOccured) const SizedBox(height: 38), if (_errorOccured) const SizedBox(height: 30),
if (_errorOccured) if (_errorOccured)
DidvanButton( DidvanButton(
width: 120, width: 120,

View File

@ -64,7 +64,7 @@ class UserProvider extends CoreProvier {
appState = AppState.idle; appState = AppState.idle;
return true; return true;
} }
appState = AppState.failed; appState = AppState.idle;
return false; return false;
} }

View File

@ -24,7 +24,6 @@ import 'package:didvan/pages/home/settings/general_settings/settings_state.dart'
import 'package:didvan/pages/home/settings/profile/profile.dart'; import 'package:didvan/pages/home/settings/profile/profile.dart';
import 'package:didvan/pages/splash/splash.dart'; import 'package:didvan/pages/splash/splash.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
import 'package:didvan/widgets/image_cropper.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -67,12 +66,6 @@ class RouteGenerator {
return _createRoute( return _createRoute(
const AboutUs(), const AboutUs(),
); );
case Routes.imageCropper:
return _createRoute(
ImageCropper(
data: settings.arguments as Map<String, dynamic>,
),
);
case Routes.generalSettings: case Routes.generalSettings:
return _createRoute( return _createRoute(
ChangeNotifierProvider<GeneralSettingsState>( ChangeNotifierProvider<GeneralSettingsState>(

View File

@ -1,201 +0,0 @@
import 'package:crop/crop.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:flutter/material.dart';
class ImageCropper extends StatefulWidget {
final Map<String, dynamic> data;
const ImageCropper({Key? key, required this.data}) : super(key: key);
@override
State<ImageCropper> createState() => _ImageCropperState();
}
class _ImageCropperState extends State<ImageCropper> {
double _rotation = 0;
BoxShape shape = BoxShape.rectangle;
final _controller = CropController();
get _bytes => widget.data['bytes'];
get _onCropped => widget.data['onCropped'];
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: const Text('برش عکس'),
centerTitle: true,
actions: <Widget>[
IconButton(
onPressed: _cropImage,
tooltip: 'Crop',
icon: const Icon(Icons.crop),
)
],
),
body: Column(
children: <Widget>[
Expanded(
child: Container(
color: Colors.black,
padding: const EdgeInsets.all(8),
child: Crop(
onChanged: (decomposition) {
if (_rotation != decomposition.rotation) {
setState(() {
_rotation = ((decomposition.rotation + 180) % 360) - 180;
});
}
},
controller: _controller,
shape: shape,
child: Image.memory(
_bytes,
fit: BoxFit.cover,
),
helper: shape == BoxShape.rectangle
? Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 2),
),
)
: null,
),
),
),
Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.redo),
tooltip: 'برگرداندن',
onPressed: () {
_controller.rotation = 0;
_controller.scale = 1;
_controller.offset = Offset.zero;
setState(() {
_rotation = 0;
});
},
),
Expanded(
child: SliderTheme(
data: theme.sliderTheme.copyWith(
trackShape: const RectangularSliderTrackShape(),
),
child: Slider(
thumbColor: Theme.of(context).colorScheme.title,
divisions: 360,
value: _rotation,
min: -180,
max: 180,
label: '$_rotation°',
onChanged: (n) {
setState(() {
_rotation = n.roundToDouble();
_controller.rotation = _rotation;
});
},
),
),
),
// PopupMenuButton<BoxShape>(
// icon: const Icon(Icons.crop_free),
// itemBuilder: (context) => [
// const PopupMenuItem(
// child: Text("Box"),
// value: BoxShape.rectangle,
// ),
// const PopupMenuItem(
// child: Text("Oval"),
// value: BoxShape.circle,
// ),
// ],
// tooltip: 'Crop Shape',
// onSelected: (x) {
// setState(() {
// shape = x;
// });
// },
// ),
// PopupMenuButton<double>(
// icon: const Icon(Icons.aspect_ratio),
// itemBuilder: (context) => [
// const PopupMenuItem(
// child: Text("Original"),
// value: 1000 / 667.0,
// ),
// const PopupMenuDivider(),
// const PopupMenuItem(
// child: Text("16:9"),
// value: 16.0 / 9.0,
// ),
// const PopupMenuItem(
// child: Text("4:3"),
// value: 4.0 / 3.0,
// ),
// const PopupMenuItem(
// child: Text("1:1"),
// value: 1,
// ),
// const PopupMenuItem(
// child: Text("3:4"),
// value: 3.0 / 4.0,
// ),
// const PopupMenuItem(
// child: Text("9:16"),
// value: 9.0 / 16.0,
// ),
// ],
// tooltip: 'Aspect Ratio',
// onSelected: (x) {
// _controller.aspectRatio = x;
// setState(() {});
// },
// ),
],
),
],
),
);
}
void _cropImage() async {
final pixelRatio = MediaQuery.of(context).devicePixelRatio;
final cropped = await _controller.crop(pixelRatio: pixelRatio);
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Scaffold(
appBar: AppBar(
title: const Text('تایید برش'),
centerTitle: true,
actions: [
Builder(
builder: (context) => IconButton(
icon: const Icon(
DidvanIcons.check_circle_solid,
size: 32,
),
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).pop();
_onCropped();
},
),
),
],
),
body: Center(
child: RawImage(
image: cropped,
),
),
),
fullscreenDialog: true,
),
);
}
}

View File

@ -92,20 +92,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.15.0" version: "1.15.0"
collision:
dependency: transitive
description:
name: collision
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.3"
crop:
dependency: "direct main"
description:
name: crop
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.2"
cross_file: cross_file:
dependency: transitive dependency: transitive
description: description:
@ -308,6 +294,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.0.0" version: "4.0.0"
image_cropper:
dependency: "direct main"
description:
name: image_cropper
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.0"
image_picker: image_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -656,13 +649,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.8" version: "0.4.8"
transparent_image:
dependency: "direct main"
description:
name: transparent_image
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:

View File

@ -57,10 +57,10 @@ dependencies:
bot_toast: ^4.0.1 bot_toast: ^4.0.1
flutter_secure_storage: ^5.0.2 flutter_secure_storage: ^5.0.2
flutter_html: ^3.0.0-alpha.2 flutter_html: ^3.0.0-alpha.2
crop: ^0.5.2
url_launcher: ^6.0.18 url_launcher: ^6.0.18
transparent_image: ^2.0.0
audio_video_progress_bar: ^0.10.0 audio_video_progress_bar: ^0.10.0
image_cropper: ^1.5.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: