Skip to content

Commit

Permalink
Updated Photo Crop Service
Browse files Browse the repository at this point in the history
  • Loading branch information
abdulmominsakib committed Oct 17, 2024
1 parent 568aa5b commit f93ebe9
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 39 deletions.
8 changes: 6 additions & 2 deletions lib/core/auth/controllers/login_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class LoginController extends GetxController {
isEmailVerified = userCredintial.user!.emailVerified;

// let's redirect 🚀
if (isAdmin && isEmailVerified) {
if (isAdmin) {
// this is admin logging in
currentAuthState.value = AuthState.adminLoggedIn;
Get.offAll(() => const EntryPointUI());
Expand Down Expand Up @@ -106,7 +106,11 @@ class LoginController extends GetxController {
isAdmin = await UserServices.isAnAdmin(user.uid);
isEmailVerified = user.emailVerified;
if (!isEmailVerified) {
currentAuthState.value = AuthState.emailUnverified;
if (isAdmin) {
currentAuthState.value = AuthState.adminLoggedIn;
} else {
currentAuthState.value = AuthState.emailUnverified;
}
} else {
if (isAdmin) currentAuthState.value = AuthState.adminLoggedIn;
if (!isAdmin) currentAuthState.value = AuthState.userLoggedIn;
Expand Down
141 changes: 119 additions & 22 deletions lib/core/data/services/app_photo.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:http/http.dart' as http;
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:worker_manager/worker_manager.dart';

class AppPhotoService {
static Future<File?> getImageFromGallery() async {
Expand All @@ -16,10 +20,7 @@ class AppPhotoService {
);

if (pickedFile != null) {
return workerManager.execute<File?>(
() => _processAndCropImage(pickedFile.path),
priority: WorkPriority.high,
);
return _isolateTask(_processAndCropImage, pickedFile.path);
} else {
print('No image selected.');
return null;
Expand All @@ -34,12 +35,9 @@ class AppPhotoService {
);

if (pickedFile != null) {
return workerManager.execute<File?>(
() => _processAndCropImage(pickedFile.path),
priority: WorkPriority.high,
);
return _isolateTask(_processAndCropImage, pickedFile.path);
} else {
print('No image selected.');
print('No image captured.');
return null;
}
}
Expand All @@ -50,27 +48,39 @@ class AppPhotoService {
}

static Future<File?> _goToImageCropper(File? imageFile) async {
if (imageFile == null) return null;
if (imageFile == null) {
print('No image selected.');
return null;
} else {
print('Image path: ${imageFile.path}');

final croppedFile = await ImageCropper().cropImage(
sourcePath: imageFile.path,
aspectRatio: const CropAspectRatio(ratioX: 1, ratioY: 1),
);
final croppedFile = await ImageCropper().cropImage(
sourcePath: imageFile.path,
aspectRatio: const CropAspectRatio(ratioX: 1, ratioY: 1),
);

if (croppedFile == null) {
print('Image cropping cancelled or failed.');
return null;
} else {
print('Cropped image path: ${croppedFile.path}');

if (croppedFile == null) return null;
// Create a File object directly from the path
final File imageFile = File(croppedFile.path);

final myFile = await croppedFile.readAsBytes();
return File.fromRawPath(myFile);
// Print the path to verify
print('Selected image path: ${imageFile.path}');

return imageFile;
}
}
}

static Future<File> fileFromImageUrl(String imageUrl) async {
File? cachedImage = await getImageFromCache(imageUrl);
if (cachedImage != null) return cachedImage;

return workerManager.execute<File>(
() => downloadAndSaveImage(imageUrl),
priority: WorkPriority.high,
);
return _isolateTask(downloadAndSaveImage, imageUrl);
}

static Future<File> downloadAndSaveImage(String imageUrl) async {
Expand All @@ -86,4 +96,91 @@ class AppPhotoService {
final fileInfo = await DefaultCacheManager().getFileFromCache(imageUrl);
return fileInfo?.file;
}

static Future<T> _isolateTask<T>(Function task, dynamic arg) async {
final ReceivePort receivePort = ReceivePort();
final isolate = await Isolate.spawn(
_isolateEntry,
IsolateData(receivePort.sendPort, task, arg),
debugName: 'ImageProcessingIsolate',
);

final result = await receivePort.first as T;
receivePort.close();
isolate.kill();
return result;
}

static void _isolateEntry(IsolateData data) async {
// Initialize BackgroundIsolateBinaryMessenger
BackgroundIsolateBinaryMessenger.ensureInitialized(data.token);

final result = await data.task(data.arg);
data.sendPort.send(result);
}

// static Future<File?> downloadImageWithProgress(String imageUrl) async {
// final ReceivePort receivePort = ReceivePort();
// final token = RootIsolateToken.instance!;
// final isolate = await Isolate.spawn(
// _downloadWithProgressEntry,
// DownloadData(receivePort.sendPort, imageUrl, token),
// debugName: 'ImageDownloadIsolate',
// );

// File? downloadedFile;
// await for (var message in receivePort) {
// if (message is double) {
// print('Download progress: ${message.toStringAsFixed(2)}%');
// } else if (message is File) {
// downloadedFile = message;
// break;
// }
// }

// receivePort.close();
// isolate.kill();
// return downloadedFile;
// }

// static void _downloadWithProgressEntry(DownloadData data) async {
// // Initialize BackgroundIsolateBinaryMessenger
// BackgroundIsolateBinaryMessenger.ensureInitialized(data.token);

// final response = await http.get(Uri.parse(data.imageUrl));
// final documentDirectory = await getApplicationDocumentsDirectory();
// final file = File(
// '${documentDirectory.path}/downloaded_image_${DateTime.now().millisecondsSinceEpoch}');

// final totalBytes = response.contentLength ?? 0;
// var downloadedBytes = 0;

// final sink = file.openWrite();
// await for (var chunk in response.body.split('')) {
// sink.add(chunk.codeUnits);
// downloadedBytes += chunk.length;
// data.sendPort.send((downloadedBytes / totalBytes) * 100);
// }
// await sink.close();

// data.sendPort.send(file);
// }
}

class IsolateData {
final SendPort sendPort;
final Function task;
final dynamic arg;
final RootIsolateToken token;

IsolateData(this.sendPort, this.task, this.arg)
: token = RootIsolateToken.instance!;
}

class DownloadData {
final SendPort sendPort;
final String imageUrl;
final RootIsolateToken token;

DownloadData(this.sendPort, this.imageUrl, this.token);
}
13 changes: 8 additions & 5 deletions lib/core/native_bridge/native_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ class NativeSDKFunctions {

/// Initiate Database of Users to letter verify
static Future<bool> setSdkDatabase(Map<int, Uint8List> userLists) async {
Get.find<CoreController>().settingSDK();
bool isDone =
await _channel.invokeMethod('setDatabase', {'membersList': userLists});
Get.find<CoreController>().settingSdkDone();
AppToast.show('Face Data Updated');
bool isDone = false;
if (userLists.isNotEmpty) {
Get.find<CoreController>().settingSDK();
isDone = await _channel
.invokeMethod('setDatabase', {'membersList': userLists});
Get.find<CoreController>().settingSdkDone();
AppToast.show('Face Data Updated');
}
return isDone;
}

Expand Down
12 changes: 6 additions & 6 deletions lib/core/widgets/app_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ class AppButton extends StatelessWidget {
const EdgeInsets.symmetric(horizontal: 14, vertical: 14),
width: width,
child: isLoading
? const CircularProgressIndicator(
color: Colors.white,
strokeWidth: 3,
? const FittedBox(
child: CircularProgressIndicator(
color: Colors.white,
),
)
: Row(
mainAxisSize: MainAxisSize.min,
Expand Down Expand Up @@ -145,10 +146,9 @@ class AppButtonOutline extends StatelessWidget {
alignment: Alignment.center,
width: width,
child: isLoading
? const AspectRatio(
aspectRatio: 1 / 1,
? const FittedBox(
child: CircularProgressIndicator(
color: Colors.white,
color: AppColors.primaryColor,
),
)
: Row(
Expand Down
2 changes: 2 additions & 0 deletions lib/features/05_members/views/dialogs/camera_or_gallery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class CameraGallerySelectDialog extends StatelessWidget {
onTap: () async {
File? image =
await AppPhotoService.getImageFromGallery();

print("selected image path: ${image?.path}");
Get.back(result: image);
},
child: Column(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:face_attendance/core/data/repository/face_repo.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../../../core/auth/controllers/login_controller.dart';
Expand Down Expand Up @@ -31,6 +32,7 @@ class AppAdminController extends GetxController {
await _collectionReference.doc(_currentUserID).get().then((value) {
currentUser = AppUser.fromDocumentSnap(value);
isUserInitialized = true;
debugPrint("Current user ${currentUser.name}");
update();
});
} catch (e) {
Expand Down
3 changes: 2 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:firebase_core/firebase_core.dart';
Expand All @@ -25,7 +26,7 @@ void main() async {
await GetStorage.init();
AppUiUtil.autoRotateOff();
final core = Get.put(CoreController());
await w.workerManager.init();
await w.workerManager.init(dynamicSpawning: true);

runApp(TuringTechApp(core: core));
}, (Object error, StackTrace stack) {
Expand Down
4 changes: 2 additions & 2 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1153,10 +1153,10 @@ packages:
dependency: "direct main"
description:
name: worker_manager
sha256: "8de97b794040a988b41f475ab0efa03015cc8dff8e130fa3606043572abb4a2c"
sha256: "0c6c4e7d246bcbe7221273ef955732dafb097347d536ebe6acd6547d0398c49c"
url: "https://pub.dev"
source: hosted
version: "7.0.3"
version: "7.2.2"
xdg_directories:
dependency: transitive
description:
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ dependencies:
encrypt: ^5.0.1
visibility_detector: ^0.4.0+2
dartz: ^0.10.0
worker_manager: ^7.0.3
worker_manager: ^7.2.2
persistent_bottom_nav_bar: ^6.2.1
auto_size_text: ^3.0.0
firebase_crashlytics: ^3.5.7
Expand Down

0 comments on commit f93ebe9

Please sign in to comment.