Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crop profile picture feature and improve comment display #50

Merged
merged 4 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</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.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
Expand Down
13 changes: 13 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ PODS:
- Flutter
- geolocator_apple (1.2.0):
- Flutter
- image_cropper (0.0.4):
- Flutter
- TOCropViewController (~> 2.6.1)
- image_gallery_saver (2.0.2):
- Flutter
- image_picker_ios (0.0.1):
Expand All @@ -20,6 +23,7 @@ PODS:
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- TOCropViewController (2.6.1)
- wakelock (0.0.1):
- Flutter

Expand All @@ -29,13 +33,18 @@ DEPENDENCIES:
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- flutter_tts (from `.symlinks/plugins/flutter_tts/ios`)
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/ios`)
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
- image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- wakelock (from `.symlinks/plugins/wakelock/ios`)

SPEC REPOS:
trunk:
- TOCropViewController

EXTERNAL SOURCES:
Flutter:
:path: Flutter
Expand All @@ -47,6 +56,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_tts/ios"
geolocator_apple:
:path: ".symlinks/plugins/geolocator_apple/ios"
image_cropper:
:path: ".symlinks/plugins/image_cropper/ios"
image_gallery_saver:
:path: ".symlinks/plugins/image_gallery_saver/ios"
image_picker_ios:
Expand All @@ -66,11 +77,13 @@ SPEC CHECKSUMS:
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d
geolocator_apple: 9157311f654584b9bb72686c55fc02a97b73f461
image_cropper: a3291c624a953049bc6a02e1f8c8ceb162a24b25
image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb
image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f

PODFILE CHECKSUM: 2442f0b84dc733c75ff32e76bcf04626a168288b
Expand Down
33 changes: 15 additions & 18 deletions lib/presentation/common/activity/widgets/activity_comments.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,21 @@ class ActivityComments extends HookConsumerWidget {
final GlobalKey<FormState> formKey;

final currentUserPictureDataProvider =
FutureProvider.family<String?, Activity>((ref, activity) async {
FutureProvider.family<ImageProvider?, Activity>((ref, activity) async {
final user = await StorageUtils.getUser();
final provider =
ref.read(activityItemViewModelProvider(activity.id).notifier);

user != null ? provider.getProfilePicture(user.id) : null;
return user?.id;

if (user?.id != null) {
final profilePicture =
ref.watch(profilePictureViewModelProvider(user!.id)).profilePicture;
return profilePicture != null
? MemoryImage(profilePicture)
: await ColorUtils.colorToImageProvider((Colors.white70));
}
return await ColorUtils.colorToImageProvider(Colors.white70);
});

final commentUserPictureDataProvider =
Expand Down Expand Up @@ -90,7 +98,6 @@ class ActivityComments extends HookConsumerWidget {
overflow: TextOverflow.visible,
),
),
const Spacer(),
if (currentUser.id == comment.user.id)
IconButton(
color: ColorUtils.black,
Expand Down Expand Up @@ -201,24 +208,14 @@ class ActivityComments extends HookConsumerWidget {
height: state.comments.isNotEmpty ? 210 : 80,
child: CommentBox(
userImage: currentUserPictureProvider.when(
data: (userId) {
if (userId != null) {
final profilePicture = ref
.watch(profilePictureViewModelProvider(userId))
.profilePicture;
return profilePicture != null
? MemoryImage(profilePicture)
: null;
}
return null;
},
loading: () => null,
error: (_, __) => null,
),
data: (picture) {
return picture;
},
loading: () => null,
error: (_, __) => null),
sendButtonMethod: () => commentsProvider.comment(currentActivity),
formKey: formKey,
commentController: commentsProvider.commentController,
backgroundColor: ColorUtils.white,
textColor: ColorUtils.mainMedium,
sendWidget:
Icon(Icons.send_sharp, size: 30, color: ColorUtils.main),
Expand Down
18 changes: 18 additions & 0 deletions lib/presentation/common/core/utils/color_utils.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:ui' as ui;

import 'package:flutter/material.dart';

/// Utility class for color-related operations.
Expand Down Expand Up @@ -66,6 +68,22 @@ class ColorUtils {
final lightColor = generateLightColor(baseColor);
return [darkColor, lightColor];
}

static Future<ImageProvider<Object>?> colorToImageProvider(Color color,
{double width = 32.0, double height = 32.0}) async {
final recorder = ui.PictureRecorder();
final canvas = Canvas(recorder);
final paint = Paint()..color = color;
canvas.drawRect(Rect.fromLTRB(0, 0, width, height), paint);
final picture = recorder.endRecording();
final img = await picture.toImage(width.toInt(), height.toInt());
final byteData = await img.toByteData(format: ui.ImageByteFormat.png);
if (byteData != null) {
return MemoryImage(byteData.buffer.asUint8List());
} else {
return null;
}
}
}

/// Extension methods for the [Color] class.
Expand Down
30 changes: 27 additions & 3 deletions lib/presentation/common/core/widgets/upload_file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
import '../utils/ui_utils.dart';

import '../utils/color_utils.dart';
import '../utils/ui_utils.dart';

/// A widget that allow to upload a file
class UploadFileWidget extends HookConsumerWidget {
Expand Down Expand Up @@ -61,9 +62,32 @@ class UploadFileWidget extends HookConsumerWidget {
await _picker.pickImage(source: ImageSource.gallery);

if (pickedImage != null) {
Uint8List file = await pickedImage.readAsBytes();
CroppedFile? croppedFile = await ImageCropper().cropImage(
sourcePath: pickedImage.path,
aspectRatioPresets: [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
],
uiSettings: [
AndroidUiSettings(
toolbarTitle: 'Cropper',
toolbarColor: ColorUtils.main,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.square,
lockAspectRatio: false),
IOSUiSettings(
title: 'Cropper',
),
],
);

callbackFunc(file);
if (croppedFile != null) {
Uint8List file = await croppedFile.readAsBytes();
callbackFunc(file);
}
}
},
child: Text(AppLocalizations.of(context)!.profile_picture_select,
Expand Down
24 changes: 24 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.1.6"
image_cropper:
dependency: "direct main"
description:
name: image_cropper
sha256: f4bad5ed2dfff5a7ce0dfbad545b46a945c702bb6182a921488ef01ba7693111
url: "https://pub.dev"
source: hosted
version: "5.0.1"
image_cropper_for_web:
dependency: transitive
description:
name: image_cropper_for_web
sha256: "865d798b5c9d826f1185b32e5d0018c4183ddb77b7b82a931e1a06aa3b74974e"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
image_cropper_platform_interface:
dependency: transitive
description:
name: image_cropper_platform_interface
sha256: ee160d686422272aa306125f3b6fb1c1894d9b87a5e20ed33fa008e7285da11e
url: "https://pub.dev"
source: hosted
version: "5.0.0"
image_gallery_saver:
dependency: "direct main"
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ dependencies:
image_picker: ^1.0.4
share_plus: ^6.3.4
comment_box: ^0.0.18
image_cropper: ^5.0.1

dev_dependencies:
flutter_test:
Expand Down
Binary file modified screenshots/community/all_activities.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading