🐛 Fix platform specific bugs & crashes
This commit is contained in:
		| @@ -29,6 +29,8 @@ abstract class PlatformInfo { | |||||||
|  |  | ||||||
|   static bool get canRateTheApp => isIOS || isMacOS; |   static bool get canRateTheApp => isIOS || isMacOS; | ||||||
|  |  | ||||||
|  |   static bool get canCropImage => isIOS || isAndroid || isWeb; | ||||||
|  |  | ||||||
|   static bool get canRecord => (isMobile || isMacOS); |   static bool get canRecord => (isMobile || isMacOS); | ||||||
|  |  | ||||||
|   static bool get canPushNotification => isAndroid || isIOS || isMacOS; |   static bool get canPushNotification => isAndroid || isIOS || isMacOS; | ||||||
|   | |||||||
| @@ -1,5 +1,3 @@ | |||||||
| import 'dart:io'; |  | ||||||
|  |  | ||||||
| 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:gap/gap.dart'; | import 'package:gap/gap.dart'; | ||||||
| @@ -9,6 +7,7 @@ import 'package:image_picker/image_picker.dart'; | |||||||
| import 'package:intl/intl.dart'; | import 'package:intl/intl.dart'; | ||||||
| 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/providers/auth.dart'; | import 'package:solian/providers/auth.dart'; | ||||||
| import 'package:solian/providers/content/attachment.dart'; | import 'package:solian/providers/content/attachment.dart'; | ||||||
| import 'package:solian/services.dart'; | import 'package:solian/services.dart'; | ||||||
| @@ -77,36 +76,42 @@ class _PersonalizeScreenState extends State<PersonalizeScreen> { | |||||||
|     final AuthProvider auth = Get.find(); |     final AuthProvider auth = Get.find(); | ||||||
|     if (auth.isAuthorized.isFalse) return; |     if (auth.isAuthorized.isFalse) return; | ||||||
|  |  | ||||||
|  |     XFile file; | ||||||
|  |  | ||||||
|     final image = await _imagePicker.pickImage(source: ImageSource.gallery); |     final image = await _imagePicker.pickImage(source: ImageSource.gallery); | ||||||
|     if (image == null) return; |     if (image == null) return; | ||||||
|  |  | ||||||
|     CroppedFile? croppedFile = await ImageCropper().cropImage( |     if (PlatformInfo.canCropImage) { | ||||||
|       sourcePath: image.path, |       CroppedFile? croppedFile = await ImageCropper().cropImage( | ||||||
|       uiSettings: [ |         sourcePath: image.path, | ||||||
|         AndroidUiSettings( |         uiSettings: [ | ||||||
|           toolbarTitle: 'cropImage'.tr, |           AndroidUiSettings( | ||||||
|           toolbarColor: Theme.of(context).colorScheme.primary, |             toolbarTitle: 'cropImage'.tr, | ||||||
|           toolbarWidgetColor: Theme.of(context).colorScheme.onPrimary, |             toolbarColor: Theme.of(context).colorScheme.primary, | ||||||
|           aspectRatioPresets: [ |             toolbarWidgetColor: Theme.of(context).colorScheme.onPrimary, | ||||||
|             if (position == 'avatar') CropAspectRatioPreset.square, |             aspectRatioPresets: [ | ||||||
|             if (position == 'banner') _BannerCropAspectRatioPreset(), |               if (position == 'avatar') CropAspectRatioPreset.square, | ||||||
|           ], |               if (position == 'banner') _BannerCropAspectRatioPreset(), | ||||||
|         ), |             ], | ||||||
|         IOSUiSettings( |           ), | ||||||
|           title: 'cropImage'.tr, |           IOSUiSettings( | ||||||
|           aspectRatioPresets: [ |             title: 'cropImage'.tr, | ||||||
|             if (position == 'avatar') CropAspectRatioPreset.square, |             aspectRatioPresets: [ | ||||||
|             if (position == 'banner') _BannerCropAspectRatioPreset(), |               if (position == 'avatar') CropAspectRatioPreset.square, | ||||||
|           ], |               if (position == 'banner') _BannerCropAspectRatioPreset(), | ||||||
|         ), |             ], | ||||||
|         WebUiSettings( |           ), | ||||||
|           context: context, |           WebUiSettings( | ||||||
|         ), |             context: context, | ||||||
|       ], |           ), | ||||||
|     ); |         ], | ||||||
|  |       ); | ||||||
|  |  | ||||||
|     if (croppedFile == null) return; |       if (croppedFile == null) return; | ||||||
|     final file = File(croppedFile.path); |       file = XFile(croppedFile.path); | ||||||
|  |     } else { | ||||||
|  |       file = XFile(image.path); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     setState(() => _isBusy = true); |     setState(() => _isBusy = true); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -289,7 +289,7 @@ class _ChatListState extends State<ChatList> { | |||||||
|                             ..._realmChannels.values.expand((x) => x), |                             ..._realmChannels.values.expand((x) => x), | ||||||
|                           ]), |                           ]), | ||||||
|                           selfId: selfId, |                           selfId: selfId, | ||||||
|                           useReplace: false, |                           useReplace: AppTheme.isLargeScreen(context), | ||||||
|                         ), |                         ), | ||||||
|                       ), |                       ), | ||||||
|                       RefreshIndicator( |                       RefreshIndicator( | ||||||
| @@ -297,7 +297,7 @@ class _ChatListState extends State<ChatList> { | |||||||
|                         child: ChannelListWidget( |                         child: ChannelListWidget( | ||||||
|                           channels: _directChannels, |                           channels: _directChannels, | ||||||
|                           selfId: selfId, |                           selfId: selfId, | ||||||
|                           useReplace: false, |                           useReplace: AppTheme.isLargeScreen(context), | ||||||
|                         ), |                         ), | ||||||
|                       ), |                       ), | ||||||
|                       ...realms.availableRealms.map( |                       ...realms.availableRealms.map( | ||||||
| @@ -306,7 +306,7 @@ class _ChatListState extends State<ChatList> { | |||||||
|                           child: ChannelListWidget( |                           child: ChannelListWidget( | ||||||
|                             channels: _realmChannels[x.alias] ?? [], |                             channels: _realmChannels[x.alias] ?? [], | ||||||
|                             selfId: selfId, |                             selfId: selfId, | ||||||
|                             useReplace: false, |                             useReplace: AppTheme.isLargeScreen(context), | ||||||
|                           ), |                           ), | ||||||
|                         ), |                         ), | ||||||
|                       ), |                       ), | ||||||
|   | |||||||
| @@ -1,5 +1,3 @@ | |||||||
| import 'dart:io'; |  | ||||||
|  |  | ||||||
| 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'; | ||||||
| @@ -8,6 +6,7 @@ import 'package:image_picker/image_picker.dart'; | |||||||
| 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/models/realm.dart'; | import 'package:solian/models/realm.dart'; | ||||||
|  | import 'package:solian/platform.dart'; | ||||||
| import 'package:solian/providers/auth.dart'; | import 'package:solian/providers/auth.dart'; | ||||||
| import 'package:solian/providers/content/attachment.dart'; | import 'package:solian/providers/content/attachment.dart'; | ||||||
| import 'package:solian/router.dart'; | import 'package:solian/router.dart'; | ||||||
| @@ -84,36 +83,42 @@ class _RealmOrganizeScreenState extends State<RealmOrganizeScreen> { | |||||||
|     final AuthProvider auth = Get.find(); |     final AuthProvider auth = Get.find(); | ||||||
|     if (auth.isAuthorized.isFalse) return; |     if (auth.isAuthorized.isFalse) return; | ||||||
|  |  | ||||||
|  |     XFile file; | ||||||
|  |  | ||||||
|     final image = await _imagePicker.pickImage(source: ImageSource.gallery); |     final image = await _imagePicker.pickImage(source: ImageSource.gallery); | ||||||
|     if (image == null) return; |     if (image == null) return; | ||||||
|  |  | ||||||
|     CroppedFile? croppedFile = await ImageCropper().cropImage( |     if (PlatformInfo.canCropImage) { | ||||||
|       sourcePath: image.path, |       CroppedFile? croppedFile = await ImageCropper().cropImage( | ||||||
|       uiSettings: [ |         sourcePath: image.path, | ||||||
|         AndroidUiSettings( |         uiSettings: [ | ||||||
|           toolbarTitle: 'cropImage'.tr, |           AndroidUiSettings( | ||||||
|           toolbarColor: Theme.of(context).colorScheme.primary, |             toolbarTitle: 'cropImage'.tr, | ||||||
|           toolbarWidgetColor: Theme.of(context).colorScheme.onPrimary, |             toolbarColor: Theme.of(context).colorScheme.primary, | ||||||
|           aspectRatioPresets: [ |             toolbarWidgetColor: Theme.of(context).colorScheme.onPrimary, | ||||||
|             if (position == 'avatar') CropAspectRatioPreset.square, |             aspectRatioPresets: [ | ||||||
|             if (position == 'banner') _BannerCropAspectRatioPreset(), |               if (position == 'avatar') CropAspectRatioPreset.square, | ||||||
|           ], |               if (position == 'banner') _BannerCropAspectRatioPreset(), | ||||||
|         ), |             ], | ||||||
|         IOSUiSettings( |           ), | ||||||
|           title: 'cropImage'.tr, |           IOSUiSettings( | ||||||
|           aspectRatioPresets: [ |             title: 'cropImage'.tr, | ||||||
|             if (position == 'avatar') CropAspectRatioPreset.square, |             aspectRatioPresets: [ | ||||||
|             if (position == 'banner') _BannerCropAspectRatioPreset(), |               if (position == 'avatar') CropAspectRatioPreset.square, | ||||||
|           ], |               if (position == 'banner') _BannerCropAspectRatioPreset(), | ||||||
|         ), |             ], | ||||||
|         WebUiSettings( |           ), | ||||||
|           context: context, |           WebUiSettings( | ||||||
|         ), |             context: context, | ||||||
|       ], |           ), | ||||||
|     ); |         ], | ||||||
|  |       ); | ||||||
|  |  | ||||||
|     if (croppedFile == null) return; |       if (croppedFile == null) return; | ||||||
|     final file = File(croppedFile.path); |       file = XFile(croppedFile.path); | ||||||
|  |     } else { | ||||||
|  |       file = XFile(image.path); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     setState(() => _isBusy = true); |     setState(() => _isBusy = true); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -396,7 +396,8 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> { | |||||||
|                     ), |                     ), | ||||||
|                   if (!element.isCompleted && |                   if (!element.isCompleted && | ||||||
|                       element.error == null && |                       element.error == null && | ||||||
|                       canBeCrop) |                       canBeCrop && | ||||||
|  |                       PlatformInfo.canCropImage) | ||||||
|                     Obx( |                     Obx( | ||||||
|                       () => IconButton( |                       () => IconButton( | ||||||
|                         color: Colors.teal, |                         color: Colors.teal, | ||||||
|   | |||||||
| @@ -1,4 +1,7 @@ | |||||||
|  | import 'dart:math'; | ||||||
|  |  | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:get/get.dart'; | ||||||
| import 'package:solian/router.dart'; | import 'package:solian/router.dart'; | ||||||
| import 'package:solian/widgets/navigation/app_navigation.dart'; | import 'package:solian/widgets/navigation/app_navigation.dart'; | ||||||
|  |  | ||||||
| @@ -54,6 +57,9 @@ class _AppNavigationRailState extends State<AppNavigationRail> { | |||||||
|         setState(() => _currentIndex = idx); |         setState(() => _currentIndex = idx); | ||||||
|         AppRouter.instance.goNamed(AppNavigation.destinations[idx].page); |         AppRouter.instance.goNamed(AppNavigation.destinations[idx].page); | ||||||
|       }, |       }, | ||||||
|  |     ).paddingOnly( | ||||||
|  |       top: max(16, MediaQuery.of(context).padding.top), | ||||||
|  |       bottom: max(16, MediaQuery.of(context).padding.bottom), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -57,5 +57,11 @@ | |||||||
| 		<string>INStartCallIntent</string> | 		<string>INStartCallIntent</string> | ||||||
| 		<string>INSendMessageIntent</string> | 		<string>INSendMessageIntent</string> | ||||||
| 	</array> | 	</array> | ||||||
|  | 	<key>NSCameraUsageDescription</key> | ||||||
|  | 	<string>Allow you take photo/video for your message or post</string> | ||||||
|  | 	<key>NSMicrophoneUsageDescription</key> | ||||||
|  | 	<string>Allow you record audio for your message or post</string> | ||||||
|  | 	<key>NSPhotoLibraryUsageDescription</key> | ||||||
|  | 	<string>Allow you add photo to your message or post</string> | ||||||
| </dict> | </dict> | ||||||
| </plist> | </plist> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user