Fix: Display of ProfilePicture for Web
parent
cad532da0b
commit
d121aa3c77
|
@ -2,9 +2,15 @@ import 'package:flutter/material.dart';
|
|||
|
||||
class UserTile extends StatelessWidget {
|
||||
final String text;
|
||||
final String? profileImageUrl;
|
||||
final void Function()? onTap;
|
||||
|
||||
const UserTile({super.key, required this.text, required this.onTap});
|
||||
const UserTile({
|
||||
super.key,
|
||||
required this.text,
|
||||
this.profileImageUrl,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -19,8 +25,15 @@ class UserTile extends StatelessWidget {
|
|||
padding: const EdgeInsets.all(20),
|
||||
child: Row(
|
||||
children: [
|
||||
// icon
|
||||
const Icon(Icons.person),
|
||||
// Profile image
|
||||
if (profileImageUrl != null && profileImageUrl!.isNotEmpty)
|
||||
CircleAvatar(
|
||||
backgroundImage: NetworkImage(profileImageUrl!),
|
||||
radius: 24,
|
||||
),
|
||||
// Icon if profile image is not set
|
||||
if (profileImageUrl == null || profileImageUrl!.isEmpty)
|
||||
const Icon(Icons.person),
|
||||
|
||||
const SizedBox(width: 20),
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ class ConversationsPage extends StatelessWidget {
|
|||
Map<String, dynamic> userData, BuildContext context) {
|
||||
return UserTile(
|
||||
text: userData[Constants.dbFieldUsersEmail],
|
||||
profileImageUrl: userData[Constants.dbFieldUsersProfilePic],
|
||||
onTap: () {
|
||||
// tapped on a user -> go to chat page
|
||||
Navigator.push(
|
||||
|
|
|
@ -6,10 +6,10 @@ import 'package:firebase_storage/firebase_storage.dart';
|
|||
import 'package:image_cropper/image_cropper.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'dart:io' as io;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import '../constants.dart';
|
||||
import '../models/user_profile.dart';
|
||||
import '../utils/helper.dart';
|
||||
|
||||
class EditProfilePage extends StatefulWidget {
|
||||
final UserProfile userData;
|
||||
|
@ -25,7 +25,8 @@ class EditProfilePageState extends State<EditProfilePage> {
|
|||
late TextEditingController _nameController;
|
||||
late TextEditingController _bioController;
|
||||
String? profileImageUrl;
|
||||
io.File? _profileImage;
|
||||
io.File? _profileImage; // for android/ios
|
||||
Uint8List? _webProfileImage; // for web
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -38,12 +39,6 @@ class EditProfilePageState extends State<EditProfilePage> {
|
|||
}
|
||||
|
||||
Future<void> _pickImage() async {
|
||||
if (kIsWeb) {
|
||||
showMsg(context, 'Limitation of the web version',
|
||||
'Due to limitations of the component used in the web version, setting a profile picture is currently available only on Android and iOS.');
|
||||
return;
|
||||
}
|
||||
|
||||
final pickedFile =
|
||||
await ImagePicker().pickImage(source: ImageSource.gallery);
|
||||
|
||||
|
@ -57,7 +52,7 @@ class EditProfilePageState extends State<EditProfilePage> {
|
|||
CropAspectRatioPreset.ratio3x2,
|
||||
CropAspectRatioPreset.original,
|
||||
CropAspectRatioPreset.ratio4x3,
|
||||
CropAspectRatioPreset.ratio16x9
|
||||
CropAspectRatioPreset.ratio16x9,
|
||||
],
|
||||
uiSettings: [
|
||||
AndroidUiSettings(
|
||||
|
@ -71,26 +66,35 @@ class EditProfilePageState extends State<EditProfilePage> {
|
|||
title: 'Cropper',
|
||||
minimumAspectRatio: 1.0,
|
||||
),
|
||||
/* WebUiSettings(
|
||||
context: context,
|
||||
presentStyle: CropperPresentStyle.page,
|
||||
boundary: const CroppieBoundary(
|
||||
width: 400,
|
||||
height: 400,
|
||||
if (kIsWeb)
|
||||
WebUiSettings(
|
||||
context: context,
|
||||
presentStyle: CropperPresentStyle.page,
|
||||
boundary: const CroppieBoundary(
|
||||
width: 400,
|
||||
height: 400,
|
||||
),
|
||||
viewPort: const CroppieViewPort(
|
||||
width: 360, height: 360, type: 'circle'),
|
||||
enableExif: true,
|
||||
enableZoom: true,
|
||||
showZoomer: true,
|
||||
),
|
||||
viewPort:
|
||||
const CroppieViewPort(width: 360, height: 360, type: 'circle'),
|
||||
enableExif: true,
|
||||
enableZoom: true,
|
||||
showZoomer: true,
|
||||
),*/
|
||||
],
|
||||
);
|
||||
|
||||
if (croppedFile != null) {
|
||||
setState(() {
|
||||
_profileImage = io.File(croppedFile.path); // convert cropped file
|
||||
});
|
||||
if (kIsWeb) {
|
||||
// web specific
|
||||
Uint8List webProfileImage = await croppedFile.readAsBytes();
|
||||
setState(() {
|
||||
_webProfileImage = webProfileImage;
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
_profileImage = io.File(croppedFile.path); // convert cropped file
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +102,7 @@ class EditProfilePageState extends State<EditProfilePage> {
|
|||
void _clearProfileImage() {
|
||||
setState(() {
|
||||
_profileImage = null;
|
||||
_webProfileImage = null; // web only
|
||||
profileImageUrl = null;
|
||||
widget.userData.profilePictureUrl = null;
|
||||
});
|
||||
|
@ -110,13 +115,16 @@ class EditProfilePageState extends State<EditProfilePage> {
|
|||
if (_formKey.currentState!.validate()) {
|
||||
String uid = FirebaseAuth.instance.currentUser!.uid;
|
||||
|
||||
if (_profileImage != null) {
|
||||
if (_profileImage != null || _webProfileImage != null) {
|
||||
final storageRef = FirebaseStorage.instance
|
||||
.ref()
|
||||
.child(Constants.dbStoragePathProfiles)
|
||||
.child(uid); // filename = userid
|
||||
|
||||
if (!kIsWeb) {
|
||||
if (kIsWeb && _webProfileImage != null) {
|
||||
await storageRef.putData(_webProfileImage!);
|
||||
profileImageUrl = await storageRef.getDownloadURL();
|
||||
} else if (_profileImage != null) {
|
||||
await storageRef.putFile(_profileImage!);
|
||||
profileImageUrl = await storageRef.getDownloadURL();
|
||||
}
|
||||
|
@ -165,6 +173,7 @@ class EditProfilePageState extends State<EditProfilePage> {
|
|||
children: [
|
||||
buildAvatar(context),
|
||||
if (_profileImage != null ||
|
||||
_webProfileImage != null ||
|
||||
widget.userData.profilePictureUrl != null)
|
||||
IconButton(
|
||||
icon: Ink(
|
||||
|
@ -221,29 +230,20 @@ class EditProfilePageState extends State<EditProfilePage> {
|
|||
radius: 50,
|
||||
backgroundImage: _profileImage != null
|
||||
? FileImage(_profileImage!) as ImageProvider
|
||||
: ((widget.userData.profilePictureUrl != null &&
|
||||
widget.userData.profilePictureUrl!.isNotEmpty)
|
||||
? NetworkImage(widget.userData.profilePictureUrl!)
|
||||
as ImageProvider
|
||||
: null),
|
||||
: _webProfileImage != null
|
||||
? MemoryImage(_webProfileImage!)
|
||||
as ImageProvider // web specific
|
||||
: (widget.userData.profilePictureUrl != null &&
|
||||
widget.userData.profilePictureUrl!.isNotEmpty
|
||||
? NetworkImage(widget.userData.profilePictureUrl!)
|
||||
as ImageProvider
|
||||
: null),
|
||||
child: ClipOval(
|
||||
child: _profileImage == null &&
|
||||
_webProfileImage == null &&
|
||||
widget.userData.profilePictureUrl == null
|
||||
? const Icon(Icons.person, size: 50)
|
||||
: SizedBox(
|
||||
width: 100,
|
||||
height: 100,
|
||||
child: _profileImage != null
|
||||
? (kIsWeb
|
||||
? Image.network(_profileImage!.path)
|
||||
: Image.file(_profileImage!, fit: BoxFit.cover))
|
||||
: ((widget.userData.profilePictureUrl != null &&
|
||||
widget.userData.profilePictureUrl!.isNotEmpty)
|
||||
? Image.network(
|
||||
widget.userData.profilePictureUrl!,
|
||||
fit: BoxFit.cover)
|
||||
: null),
|
||||
),
|
||||
: null,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
|
||||
|
@ -610,13 +609,13 @@ class _UserProfilePageState extends State<UserProfilePage> {
|
|||
),
|
||||
CircleAvatar(
|
||||
radius: 50,
|
||||
backgroundImage: (!kIsWeb &&
|
||||
(profileImageUrl != null && profileImageUrl!.isNotEmpty))
|
||||
? NetworkImage(profileImageUrl!)
|
||||
: null,
|
||||
backgroundImage:
|
||||
((profileImageUrl != null && profileImageUrl!.isNotEmpty))
|
||||
? NetworkImage(profileImageUrl!)
|
||||
: null,
|
||||
child: (profileImageUrl == null || profileImageUrl!.isEmpty)
|
||||
? const Icon(Icons.person, size: 50)
|
||||
: (kIsWeb ? const Icon(Icons.broken_image, size: 50) : null),
|
||||
: null,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(myData.name, style: const TextStyle(fontSize: 24)),
|
||||
|
|
|
@ -53,7 +53,8 @@
|
|||
serviceWorkerVersion: serviceWorkerVersion,
|
||||
},
|
||||
onEntrypointLoaded: function(engineInitializer) {
|
||||
engineInitializer.initializeEngine().then(function(appRunner) {
|
||||
let config = { renderer: 'html' };
|
||||
engineInitializer.initializeEngine(config).then(function(appRunner) {
|
||||
appRunner.runApp();
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue