Crop image for profile picture, background

This commit is contained in:
2025-05-05 21:48:02 +08:00
parent f266968644
commit 937e249b87
13 changed files with 182 additions and 51 deletions

View File

@ -31,54 +31,61 @@ class AccountScreen extends HookConsumerWidget {
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (user.value?.profile.background != null)
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
topRight: Radius.circular(8),
),
child: AspectRatio(
aspectRatio: 16 / 7,
child: CloudFileWidget(
item: user.value!.profile.background!,
fit: BoxFit.cover,
GestureDetector(
child: Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (user.value?.profile.background != null)
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
topRight: Radius.circular(8),
),
child: AspectRatio(
aspectRatio: 16 / 7,
child: CloudFileWidget(
item: user.value!.profile.background!,
fit: BoxFit.cover,
),
),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 16,
children: [
ProfilePictureWidget(
fileId: user.value?.profile.pictureId,
radius: 24,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
spacing: 4,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(user.value!.nick).bold().fontSize(16),
Text('@${user.value!.name}'),
],
),
Text(
user.value!.profile.bio ?? 'No description yet.',
),
],
),
],
).padding(horizontal: 16, vertical: 16),
],
),
).padding(horizontal: 8),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 16,
children: [
ProfilePictureWidget(
fileId: user.value?.profile.pictureId,
radius: 24,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
spacing: 4,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(user.value!.nick).bold().fontSize(16),
Text('@${user.value!.name}'),
],
),
Text(
user.value!.profile.bio ?? 'No description yet.',
),
],
),
],
).padding(horizontal: 16, vertical: 16),
],
),
).padding(horizontal: 8),
onTap: () {
context.router.push(
AccountProfileRoute(name: user.value!.name),
);
},
),
const Gap(8),
ListTile(
minTileHeight: 48,

View File

@ -1,4 +1,5 @@
import 'package:auto_route/auto_route.dart';
import 'package:croppy/croppy.dart' hide cropImage;
import 'package:dio/dio.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -176,10 +177,23 @@ class EditPublisherScreen extends HookConsumerWidget {
final background = useState<SnCloudFile?>(null);
void setPicture(String position) async {
final result = await ref
var result = await ref
.read(imagePickerProvider)
.pickImage(source: ImageSource.gallery);
if (result == null) return;
if (!context.mounted) return;
result = await cropImage(
context,
image: result,
allowedAspectRatios: [
if (position == 'background')
CropAspectRatio(height: 7, width: 16)
else
CropAspectRatio(height: 1, width: 1),
],
);
if (result == null) return;
if (!context.mounted) return;
submitting.value = true;
try {

View File

@ -1,4 +1,5 @@
import 'package:auto_route/auto_route.dart';
import 'package:croppy/croppy.dart' hide cropImage;
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
@ -25,10 +26,23 @@ class UpdateProfileScreen extends HookConsumerWidget {
final submitting = useState(false);
void updateProfilePicture(String position) async {
final result = await ref
var result = await ref
.read(imagePickerProvider)
.pickImage(source: ImageSource.gallery);
if (result == null) return;
if (!context.mounted) return;
result = await cropImage(
context,
image: result,
allowedAspectRatios: [
if (position == 'background')
CropAspectRatio(height: 7, width: 16)
else
CropAspectRatio(height: 1, width: 1),
],
);
if (result == null) return;
if (!context.mounted) return;
submitting.value = true;
try {

View File

@ -1,4 +1,5 @@
import 'package:auto_route/auto_route.dart';
import 'package:croppy/croppy.dart' hide cropImage;
import 'package:dio/dio.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -244,10 +245,23 @@ class EditChatScreen extends HookConsumerWidget {
}, [chat]);
void setPicture(String position) async {
final result = await ref
var result = await ref
.read(imagePickerProvider)
.pickImage(source: ImageSource.gallery);
if (result == null) return;
if (!context.mounted) return;
result = await cropImage(
context,
image: result,
allowedAspectRatios: [
if (position == 'background')
CropAspectRatio(height: 7, width: 16)
else
CropAspectRatio(height: 1, width: 1),
],
);
if (result == null) return;
if (!context.mounted) return;
submitting.value = true;
try {

View File

@ -1,4 +1,5 @@
import 'package:auto_route/auto_route.dart';
import 'package:croppy/croppy.dart' show CropAspectRatio;
import 'package:dio/dio.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -158,10 +159,23 @@ class EditRealmScreen extends HookConsumerWidget {
}, [realm]);
void setPicture(String position) async {
final result = await ref
var result = await ref
.read(imagePickerProvider)
.pickImage(source: ImageSource.gallery);
if (result == null) return;
if (!context.mounted) return;
result = await cropImage(
context,
image: result,
allowedAspectRatios: [
if (position == 'background')
CropAspectRatio(height: 7, width: 16)
else
CropAspectRatio(height: 1, width: 1),
],
);
if (result == null) return;
if (!context.mounted) return;
submitting.value = true;
try {