diff --git a/lib/core/global_usages/constants/constants.dart b/lib/core/global_usages/constants/constants.dart index 6cbdaec..a156b0d 100644 --- a/lib/core/global_usages/constants/constants.dart +++ b/lib/core/global_usages/constants/constants.dart @@ -38,4 +38,8 @@ abstract class Constants { static const String tempDateTime = "2024-01-01 12:00:00"; static const String defaultUserImage = "assets/default_images/temp_user.jpg"; + + + // + static const String killIsolate = "kill_isolate"; } diff --git a/lib/core/utils/image_comporessor/image_compressor.dart b/lib/core/utils/image_comporessor/image_compressor.dart index 809f048..0d5f74e 100644 --- a/lib/core/utils/image_comporessor/image_compressor.dart +++ b/lib/core/utils/image_comporessor/image_compressor.dart @@ -5,7 +5,7 @@ import 'package:path/path.dart'; import 'package:yahay/features/telegram_file_picker_feature/data/models/telegram_file_image_with_compressed_and_original_path_model.dart'; abstract final class ImageCompressor { - static Future compressedImageFile({ + static Future compressedImageFile({ required File file, required String? directoryPath, int quality = 60, @@ -23,9 +23,10 @@ abstract final class ImageCompressor { if (compressedImage == null) { throw ("Failed to compress the image"); } - final result = TelegramFileImageWithCompressedAndOriginalPathModel( + final result = TelegramPathFolderFileModel( File(compressedImage.path), originalPath: file.path, + isImage: true, ); return result; } diff --git a/lib/features/telegram_file_picker_feature/data/models/telegram_file_image_with_compressed_and_original_path_model.dart b/lib/features/telegram_file_picker_feature/data/models/telegram_file_image_with_compressed_and_original_path_model.dart index 6fa77b1..25f4493 100644 --- a/lib/features/telegram_file_picker_feature/data/models/telegram_file_image_with_compressed_and_original_path_model.dart +++ b/lib/features/telegram_file_picker_feature/data/models/telegram_file_image_with_compressed_and_original_path_model.dart @@ -1,19 +1,26 @@ import 'package:yahay/features/telegram_file_picker_feature/domain/entities/telegram_file_image_with_compressed_and_original_path_entity.dart'; -final class TelegramFileImageWithCompressedAndOriginalPathModel - extends TelegramFileImageWithCompressedAndOriginalPathEntity { - TelegramFileImageWithCompressedAndOriginalPathModel( +final class TelegramPathFolderFileModel extends TelegramPathFolderFile { + TelegramPathFolderFileModel( super.file, { super.originalPath, + super.isFolder, + super.isImage, + super.isVideo, + super.fileExtension, }); - TelegramFileImageWithCompressedAndOriginalPathModel? fromEntity( - TelegramFileImageWithCompressedAndOriginalPathEntity? entity, + TelegramPathFolderFileModel? fromEntity( + TelegramPathFolderFile? entity, ) { if (entity == null) return null; - return TelegramFileImageWithCompressedAndOriginalPathModel( - file, - originalPath: originalPath, + return TelegramPathFolderFileModel( + entity.file, + originalPath: entity.originalPath, + isFolder: entity.isFolder, + isImage: entity.isImage, + isVideo: entity.isVideo, + fileExtension: entity.fileExtension, ); } } diff --git a/lib/features/telegram_file_picker_feature/data/repo/telegram_file_picker_repo_impl.dart b/lib/features/telegram_file_picker_feature/data/repo/telegram_file_picker_repo_impl.dart index 4eeaede..5d9cbdd 100644 --- a/lib/features/telegram_file_picker_feature/data/repo/telegram_file_picker_repo_impl.dart +++ b/lib/features/telegram_file_picker_feature/data/repo/telegram_file_picker_repo_impl.dart @@ -9,15 +9,15 @@ class TelegramFilePickerRepoImpl with RecentFileMixin, DownloadsPathFiles, AppStorageFileMixin implements TelegramFilePickerRepo { @override - Stream getRecentImagesAndVideos() => + Stream getRecentImagesAndVideos() => getAllImagesAndVideos(); @override - Stream getRecentFiles() => + Stream getRecentFiles() => downloadsPathFilesData(); @override - Stream getSpecificFolderData( + Stream getSpecificFolderData( String path, ) => getSpecificFolderDataStream(path); diff --git a/lib/features/telegram_file_picker_feature/domain/entities/telegram_file_image_with_compressed_and_original_path_entity.dart b/lib/features/telegram_file_picker_feature/domain/entities/telegram_file_image_with_compressed_and_original_path_entity.dart index 3ac65eb..7a4905c 100644 --- a/lib/features/telegram_file_picker_feature/domain/entities/telegram_file_image_with_compressed_and_original_path_entity.dart +++ b/lib/features/telegram_file_picker_feature/domain/entities/telegram_file_image_with_compressed_and_original_path_entity.dart @@ -1,11 +1,19 @@ import 'dart:io'; -base class TelegramFileImageWithCompressedAndOriginalPathEntity { +base class TelegramPathFolderFile { final File file; final String? originalPath; + final bool isFolder; + final bool isImage; + final bool isVideo; + final String? fileExtension; - TelegramFileImageWithCompressedAndOriginalPathEntity( + TelegramPathFolderFile( this.file, { this.originalPath, + this.isFolder = false, + this.isImage = false, + this.isVideo = false, + this.fileExtension, }); } diff --git a/lib/features/telegram_file_picker_feature/domain/repo/telegram_file_picker_repo.dart b/lib/features/telegram_file_picker_feature/domain/repo/telegram_file_picker_repo.dart index 599b4ec..b27348a 100644 --- a/lib/features/telegram_file_picker_feature/domain/repo/telegram_file_picker_repo.dart +++ b/lib/features/telegram_file_picker_feature/domain/repo/telegram_file_picker_repo.dart @@ -4,11 +4,11 @@ import 'package:yahay/features/telegram_file_picker_feature/domain/entities/tele // classes only can "implement" abstract interface class TelegramFilePickerRepo { // for getting recent files -> images and videos - Stream getRecentImagesAndVideos(); + Stream getRecentImagesAndVideos(); // for getting all download's path files here - Stream getRecentFiles(); + Stream getRecentFiles(); // for getting specific app folder data, does not matter what - Stream getSpecificFolderData(String path); + Stream getSpecificFolderData(String path); } diff --git a/lib/features/telegram_file_picker_feature/domain/usecases/file_picker_usecase/file_picker_usecase.dart b/lib/features/telegram_file_picker_feature/domain/usecases/file_picker_usecase/file_picker_usecase.dart index 4ff3fde..ac4997b 100644 --- a/lib/features/telegram_file_picker_feature/domain/usecases/file_picker_usecase/file_picker_usecase.dart +++ b/lib/features/telegram_file_picker_feature/domain/usecases/file_picker_usecase/file_picker_usecase.dart @@ -8,12 +8,12 @@ class FilePickerUseCase { FilePickerUseCase(this._filePickerRepo); // - Stream getRecentImagesAndVideos() async* { + Stream getRecentImagesAndVideos() async* { yield* _filePickerRepo.getRecentImagesAndVideos(); } // - Stream downloadsPathFilesData() async* { + Stream downloadsPathFilesData() async* { yield* _filePickerRepo.getRecentFiles(); } } diff --git a/lib/features/telegram_file_picker_feature/mixins/app_storage_file_mixin/app_storage_file_mixin.dart b/lib/features/telegram_file_picker_feature/mixins/app_storage_file_mixin/app_storage_file_mixin.dart index 6d5e9ca..23238f7 100644 --- a/lib/features/telegram_file_picker_feature/mixins/app_storage_file_mixin/app_storage_file_mixin.dart +++ b/lib/features/telegram_file_picker_feature/mixins/app_storage_file_mixin/app_storage_file_mixin.dart @@ -1,12 +1,17 @@ import 'dart:io'; import 'dart:isolate'; -import 'dart:ui'; - -import 'package:yahay/features/telegram_file_picker_feature/domain/entities/telegram_file_image_with_compressed_and_original_path_entity.dart'; +import 'package:flutter/services.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:yahay/core/global_usages/constants/constants.dart'; +import 'package:yahay/core/global_usages/reusables/reusable_global_functions.dart'; +import 'package:yahay/core/utils/image_comporessor/image_compressor.dart'; +import 'package:yahay/features/telegram_file_picker_feature/data/models/telegram_file_image_with_compressed_and_original_path_model.dart'; +import 'package:yahay/injections/injections.dart'; +import 'package:path/path.dart' as p; mixin class AppStorageFileMixin { // - Stream getSpecificFolderDataStream( + Stream getSpecificFolderDataStream( String path, ) async* { // @@ -21,18 +26,73 @@ mixin class AppStorageFileMixin { path, ]); - await for (final each in mainPort) {} + await for (final each in mainPort) { + if (each is TelegramPathFolderFileModel) { + yield each; + } else if (each is String && each == Constants.killIsolate) { + mainPort.close(); + break; + } + } } // static Future _isolateHelper(List args) async { RootIsolateToken mainRootIsolateToken = args[0] as RootIsolateToken; + + BackgroundIsolateBinaryMessenger.ensureInitialized(mainRootIsolateToken); + SendPort sendPort = args[1] as SendPort; + String path = args[2] as String; final directory = Directory(path); - if (!directory.existsSync()) return; + if (!directory.existsSync()) { + sendPort.send(Constants.killIsolate); + return; + } + + final reusables = snoopy(); + + final tempPath = await getTemporaryDirectory(); + + final data = directory.listSync(); + + for (final each in data) { + if (each.existsSync()) { + File file = File(each.path); + + if (FileSystemEntity.isDirectorySync(each.path)) { + final folder = TelegramPathFolderFileModel( + file, + isFolder: true, + ); + sendPort.send(folder); + } else if (reusables.isImageFile(each.path)) { + final compressedImage = await ImageCompressor.compressedImageFile( + file: file, + directoryPath: tempPath.path, + ); + sendPort.send(compressedImage); + return; + } else if (reusables.isVideoFile(each.path)) { + final video = TelegramPathFolderFileModel( + file, + isVideo: true, + ); + sendPort.send(video); + } else { + final otherFile = TelegramPathFolderFileModel( + file, + fileExtension: p.extension(each.path), + ); + sendPort.send(otherFile); + } + } + } + + sendPort.send(Constants.killIsolate); } // } diff --git a/lib/features/telegram_file_picker_feature/mixins/recent_file_mixin/downloads_path_files.dart b/lib/features/telegram_file_picker_feature/mixins/recent_file_mixin/downloads_path_files.dart index 7560e6c..5d41b70 100644 --- a/lib/features/telegram_file_picker_feature/mixins/recent_file_mixin/downloads_path_files.dart +++ b/lib/features/telegram_file_picker_feature/mixins/recent_file_mixin/downloads_path_files.dart @@ -7,6 +7,7 @@ import 'package:get_it/get_it.dart'; import 'package:lecle_downloads_path_provider/constants/downloads_directory_type.dart'; import 'package:lecle_downloads_path_provider/lecle_downloads_path_provider.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:yahay/core/global_usages/constants/constants.dart'; import 'package:yahay/core/global_usages/reusables/reusable_global_functions.dart'; import 'package:yahay/core/utils/image_comporessor/image_compressor.dart'; import 'package:yahay/core/utils/permissions/permissions_service.dart'; @@ -18,7 +19,7 @@ mixin class DownloadsPathFiles { // final _reusables = snoopy(); - Stream downloadsPathFilesData({ + Stream downloadsPathFilesData({ String dirType = DownloadDirectoryTypes.downloads, }) async* { try { @@ -51,9 +52,10 @@ mixin class DownloadsPathFiles { Isolate.spawn(_fileFinder, sendingList); await for (final each in sendingPort) { - if (each is TelegramFileImageWithCompressedAndOriginalPathModel) { + if (each is TelegramPathFolderFileModel) { yield each; - } else if (each == null) { + } else if (each is String && each == Constants.killIsolate) { + sendingPort.close(); break; // null indicates the end of the processing } } @@ -103,5 +105,7 @@ mixin class DownloadsPathFiles { } } } + + receivingPort.send(Constants.killIsolate); } } diff --git a/lib/features/telegram_file_picker_feature/mixins/recent_file_mixin/recent_file_mixin.dart b/lib/features/telegram_file_picker_feature/mixins/recent_file_mixin/recent_file_mixin.dart index 857b1ed..b78bc66 100644 --- a/lib/features/telegram_file_picker_feature/mixins/recent_file_mixin/recent_file_mixin.dart +++ b/lib/features/telegram_file_picker_feature/mixins/recent_file_mixin/recent_file_mixin.dart @@ -6,6 +6,7 @@ import 'package:flutter/services.dart'; import 'package:get_it/get_it.dart'; import 'package:path_provider/path_provider.dart'; import 'package:photo_manager/photo_manager.dart'; +import 'package:yahay/core/global_usages/constants/constants.dart'; import 'package:yahay/core/global_usages/reusables/reusable_global_functions.dart'; import 'package:yahay/core/utils/image_comporessor/image_compressor.dart'; import 'package:yahay/core/utils/permissions/permissions_service.dart'; @@ -20,7 +21,7 @@ mixin class RecentFileMixin { // final _reusableFunctions = snoopy(); - Stream getAllImagesAndVideos() async* { + Stream getAllImagesAndVideos() async* { try { final externalStoragePermission = await _permissions.manageExternalStoragePermission(); @@ -62,8 +63,11 @@ mixin class RecentFileMixin { ]); await for (final each in receivePort) { - if (each is TelegramFileImageWithCompressedAndOriginalPathModel) { + if (each is TelegramPathFolderFileModel) { yield each; + } else if (each is String && each == Constants.killIsolate) { + receivePort.close(); + break; } } } catch (e) { @@ -125,6 +129,8 @@ mixin class RecentFileMixin { } } } + + sendPort.send(Constants.killIsolate); } // Future _compressedFile(File? file) async { diff --git a/lib/features/telegram_file_picker_feature/view/bloc/state_model/telegram_file_picker_state_model.dart b/lib/features/telegram_file_picker_feature/view/bloc/state_model/telegram_file_picker_state_model.dart index cb26863..aa15a8a 100644 --- a/lib/features/telegram_file_picker_feature/view/bloc/state_model/telegram_file_picker_state_model.dart +++ b/lib/features/telegram_file_picker_feature/view/bloc/state_model/telegram_file_picker_state_model.dart @@ -50,14 +50,14 @@ class TelegramFilePickerStateModel { List get clonedPickedFiles => _pickedFiles.map((e) => TelegramFileImageModel.fromEntity(e)).toList(); - StreamSubscription? _fileStreamData; + StreamSubscription? _fileStreamData; - StreamSubscription? get fileStreamData => + StreamSubscription? get fileStreamData => _fileStreamData; - StreamSubscription? _recentFileData; + StreamSubscription? _recentFileData; - StreamSubscription? get recentFileData => + StreamSubscription? get recentFileData => _recentFileData; bool _openBottomSectionButton = true; @@ -135,12 +135,12 @@ class TelegramFilePickerStateModel { _recentFilesPagination.addAll(list); void initFileStreamData( - StreamSubscription stream, + StreamSubscription stream, ) => _fileStreamData = stream; void initRecentFileStreamData( - StreamSubscription stream, + StreamSubscription stream, ) => _recentFileData = stream; diff --git a/lib/features/telegram_file_picker_feature/view/bloc/telegram_file_picker_events.dart b/lib/features/telegram_file_picker_feature/view/bloc/telegram_file_picker_events.dart index 0fe3ddd..0567602 100644 --- a/lib/features/telegram_file_picker_feature/view/bloc/telegram_file_picker_events.dart +++ b/lib/features/telegram_file_picker_feature/view/bloc/telegram_file_picker_events.dart @@ -64,14 +64,14 @@ final class ClosePopupEvent extends TelegramFilePickerEvents { @immutable final class FileStreamHandlerEvent extends TelegramFilePickerEvents { - final TelegramFileImageWithCompressedAndOriginalPathEntity? file; + final TelegramPathFolderFile? file; const FileStreamHandlerEvent(this.file); } @immutable final class RecentFileStreamHandlerEvent extends TelegramFilePickerEvents { - final TelegramFileImageWithCompressedAndOriginalPathEntity? file; + final TelegramPathFolderFile? file; const RecentFileStreamHandlerEvent(this.file); }