make profile picture expandable

This commit is contained in:
2026-02-18 11:51:44 +02:00
parent 3f0fc08a5c
commit 82c25c5406
19 changed files with 138 additions and 98 deletions

View File

@@ -774,6 +774,7 @@ class _PackageToolOneState extends State<PackageToolOne> {
MihCircleAvatar( MihCircleAvatar(
imageFile: imagePreview, imageFile: imagePreview,
width: 50, width: 50,
expandable: true,
editable: false, editable: false,
fileNameController: _fileNameController, fileNameController: _fileNameController,
userSelectedfile: file, userSelectedfile: file,

View File

@@ -68,6 +68,7 @@ class _MihBusinessProfilePreviewState extends State<MihBusinessProfilePreview> {
: MihCircleAvatar( : MihCircleAvatar(
imageFile: widget.imageFile, imageFile: widget.imageFile,
width: profilePictureWidth, width: profilePictureWidth,
expandable: false,
editable: false, editable: false,
fileNameController: TextEditingController(), fileNameController: TextEditingController(),
userSelectedfile: null, userSelectedfile: null,

View File

@@ -2,13 +2,17 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:ken_logger/ken_logger.dart';
import 'package:mzansi_innovation_hub/main.dart'; import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_icons.dart'; import 'package:mzansi_innovation_hub/mih_package_components/mih_icons.dart';
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart'; import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
import 'package:mzansi_innovation_hub/mih_package_components/mih_package_window.dart';
class MihCircleAvatar extends StatefulWidget { class MihCircleAvatar extends StatefulWidget {
final ImageProvider<Object>? imageFile; final ImageProvider<Object>? imageFile;
final double width; final double width;
final bool expandable;
final bool editable; final bool editable;
final TextEditingController? fileNameController; final TextEditingController? fileNameController;
final onChange; final onChange;
@@ -19,6 +23,7 @@ class MihCircleAvatar extends StatefulWidget {
super.key, super.key,
required this.imageFile, required this.imageFile,
required this.width, required this.width,
required this.expandable,
required this.editable, required this.editable,
required this.fileNameController, required this.fileNameController,
required this.userSelectedfile, required this.userSelectedfile,
@@ -35,23 +40,30 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
late ImageProvider<Object>? imagePreview; late ImageProvider<Object>? imagePreview;
ImageProvider<Object>? getAvatar() { ImageProvider<Object>? getAvatar() {
// Color dark = const Color(0XFF3A4454);
if (widget.imageFile == null) { if (widget.imageFile == null) {
return null; return null;
// if (widget.backgroundColor == dark) {
// print("here in light icon");
// return const AssetImage(
// 'lib/mih_package_components/assets/images/i-dont-know-light.png');
// } else {
// print("here in dark icon");
// return const AssetImage(
// 'lib/mih_package_components/assets/images/i-dont-know-dark.png');
// }
} else { } else {
return widget.imageFile; return widget.imageFile;
} }
} }
void expandAvatar() {
showDialog(
context: context,
builder: (context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: "",
onWindowTapClose: () {
context.pop();
},
windowBody: InteractiveViewer(
child: Image(image: imagePreview!),
),
);
});
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@@ -62,111 +74,121 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return GestureDetector(
// color: Colors.white, onTap: widget.expandable
alignment: Alignment.center, ? () {
width: widget.width, KenLogger.success("Avatar tapped");
height: widget.width, expandAvatar();
child: Stack( }
: null,
child: Container(
alignment: Alignment.center, alignment: Alignment.center,
children: [ width: widget.width,
Visibility( height: widget.width,
visible: imagePreview != null, child: Stack(
child: Positioned( alignment: Alignment.center,
right: widget.width * 0.03, children: [
child: CircleAvatar( Visibility(
radius: widget.width / 2.2, visible: imagePreview != null,
backgroundColor: widget.backgroundColor, child: Positioned(
backgroundImage: imagePreview, right: widget.width * 0.03,
child: CircleAvatar(
radius: widget.width / 2.2,
backgroundColor: widget.backgroundColor,
backgroundImage: imagePreview,
),
), ),
), ),
), Visibility(
Visibility( visible: imagePreview != null,
visible: imagePreview != null, child: Icon(
child: Icon( size: widget.width,
size: widget.width, MihIcons.mihRing,
MihIcons.mihRing, color: widget.frameColor,
color: widget.frameColor, ),
), ),
), Visibility(
Visibility( visible: imagePreview == null,
visible: imagePreview == null, child: Icon(
child: Icon( MihIcons.iDontKnow,
MihIcons.iDontKnow, size: widget.width,
size: widget.width, color: widget.frameColor,
color: widget.frameColor, ),
), ),
), Visibility(
Visibility( visible: widget.editable,
visible: widget.editable, child: Positioned(
child: Positioned( bottom: 0,
bottom: 0, right: 0,
right: 0, child: IconButton.filled(
child: IconButton.filled( style: ButtonStyle(
style: ButtonStyle( backgroundColor: WidgetStateProperty.all<Color>(
backgroundColor: WidgetStateProperty.all<Color>( MihColors.getGreenColor(
MihColors.getGreenColor( MzansiInnovationHub.of(context)!.theme.mode ==
MzansiInnovationHub.of(context)!.theme.mode == "Dark"), "Dark"),
),
), ),
), onPressed: () async {
onPressed: () async { try {
try { FilePickerResult? result =
FilePickerResult? result = await FilePicker.platform.pickFiles(
await FilePicker.platform.pickFiles( type: FileType.image,
type: FileType.image, );
); // print("Here 1");
// print("Here 1"); if (MzansiInnovationHub.of(context)!
if (MzansiInnovationHub.of(context)!.theme.getPlatform() == .theme
"Web") { .getPlatform() ==
// print("Here 2"); "Web") {
if (result == null) return; // print("Here 2");
// print("Here 3"); if (result == null) return;
PlatformFile? selectedFile = result.files.first; // print("Here 3");
setState(() { PlatformFile? selectedFile = result.files.first;
// print("Here 4");
widget.onChange(selectedFile);
// print("Here 5");
imagePreview = MemoryImage(selectedFile.bytes!);
});
setState(() {
widget.fileNameController!.text = selectedFile.name;
});
} else {
if (result != null) {
File file = File(result.files.single.path!);
PlatformFile? androidFile = PlatformFile(
path: file.path,
name: file.path.split('/').last,
size: file.lengthSync(),
bytes: await file.readAsBytes(), // Read file bytes
//extension: fileExtension,
);
setState(() { setState(() {
widget.onChange(androidFile); // print("Here 4");
imagePreview = FileImage(file); widget.onChange(selectedFile);
// print("Here 5");
imagePreview = MemoryImage(selectedFile.bytes!);
}); });
setState(() { setState(() {
widget.fileNameController!.text = widget.fileNameController!.text = selectedFile.name;
file.path.split('/').last;
}); });
} else { } else {
print("here in else"); if (result != null) {
// User canceled the picker File file = File(result.files.single.path!);
PlatformFile? androidFile = PlatformFile(
path: file.path,
name: file.path.split('/').last,
size: file.lengthSync(),
bytes: await file.readAsBytes(), // Read file bytes
//extension: fileExtension,
);
setState(() {
widget.onChange(androidFile);
imagePreview = FileImage(file);
});
setState(() {
widget.fileNameController!.text =
file.path.split('/').last;
});
} else {
print("here in else");
// User canceled the picker
}
} }
} catch (e) {
print("Here Error: $e");
} }
} catch (e) { },
print("Here Error: $e"); icon: Icon(
} Icons.camera_alt,
}, ),
icon: Icon(
Icons.camera_alt,
), ),
), ),
), ),
), ],
], ),
), ),
); );
} }

View File

@@ -49,6 +49,7 @@ class _MihPersonalProfilePreviewState extends State<MihPersonalProfilePreview> {
: MihCircleAvatar( : MihCircleAvatar(
imageFile: widget.imageFile, imageFile: widget.imageFile,
width: profilePictureWidth, width: profilePictureWidth,
expandable: false,
editable: false, editable: false,
fileNameController: TextEditingController(), fileNameController: TextEditingController(),
userSelectedfile: null, userSelectedfile: null,

View File

@@ -78,6 +78,7 @@ class _MIHAppDrawerState extends State<MIHAppDrawer> {
? mzansiProfileProvider.userProfilePicture ? mzansiProfileProvider.userProfilePicture
: mzansiProfileProvider.businessProfilePicture, : mzansiProfileProvider.businessProfilePicture,
width: 60, width: 60,
expandable: false,
editable: false, editable: false,
fileNameController: proPicController, fileNameController: proPicController,
onChange: (_) {}, onChange: (_) {},

View File

@@ -353,6 +353,7 @@ class _MihHomeState extends State<MihHome> {
key: Key(imageKey), key: Key(imageKey),
imageFile: currentImage, imageFile: currentImage,
width: 50, width: 50,
expandable: false,
editable: false, editable: false,
fileNameController: null, fileNameController: null,
userSelectedfile: null, userSelectedfile: null,

View File

@@ -104,6 +104,7 @@ class _BuildMinesweeperLeaderboardListState
key: UniqueKey(), key: UniqueKey(),
imageFile: imageFile, imageFile: imageFile,
width: 80, width: 80,
expandable: true,
editable: false, editable: false,
fileNameController: null, fileNameController: null,
userSelectedfile: null, userSelectedfile: null,

View File

@@ -50,6 +50,7 @@ class LeaderboardUserRanking extends StatelessWidget {
.toString()), // Use ValueKey for stable identity .toString()), // Use ValueKey for stable identity
imageFile: asyncSnapshot.data, imageFile: asyncSnapshot.data,
width: 60, width: 60,
expandable: true,
editable: false, editable: false,
fileNameController: null, fileNameController: null,
userSelectedfile: null, userSelectedfile: null,

View File

@@ -87,6 +87,7 @@ class _MihMineSweeperLeaderBoardState extends State<MyScoreBoard> {
child: MihCircleAvatar( child: MihCircleAvatar(
imageFile: profileProvider.userProfilePicture, imageFile: profileProvider.userProfilePicture,
width: 150, width: 150,
expandable: true,
editable: false, editable: false,
fileNameController: null, fileNameController: null,
userSelectedfile: null, userSelectedfile: null,

View File

@@ -271,6 +271,7 @@ class _MihUpdateBusinessDetailsWindowState
: mzansiProfileProvider : mzansiProfileProvider
.businessProfilePicture, .businessProfilePicture,
width: 150, width: 150,
expandable: false,
editable: true, editable: true,
fileNameController: fileNameController, fileNameController: fileNameController,
userSelectedfile: newSelectedLogoPic, userSelectedfile: newSelectedLogoPic,

View File

@@ -77,6 +77,7 @@ class _MihBusinessDetailsState extends State<MihBusinessDetails> {
imageFile: imageFile:
mzansiProfileProvider.businessProfilePicture, mzansiProfileProvider.businessProfilePicture,
width: 150, width: 150,
expandable: true,
editable: false, editable: false,
fileNameController: fileNameController, fileNameController: fileNameController,
userSelectedfile: newSelectedLogoPic, userSelectedfile: newSelectedLogoPic,

View File

@@ -330,6 +330,7 @@ class _MihBusinessDetailsSetUpState extends State<MihBusinessDetailsSetUp> {
? MemoryImage(newSelectedLogoPic!.bytes!) ? MemoryImage(newSelectedLogoPic!.bytes!)
: mzansiProfileProvider.businessProfilePicture, : mzansiProfileProvider.businessProfilePicture,
width: 150, width: 150,
expandable: false,
editable: true, editable: true,
fileNameController: logoFileNameController, fileNameController: logoFileNameController,
userSelectedfile: newSelectedLogoPic, userSelectedfile: newSelectedLogoPic,

View File

@@ -77,6 +77,7 @@ class _MihBusinessDetailsViewState extends State<MihBusinessDetailsView> {
imageFile: CachedNetworkImageProvider( imageFile: CachedNetworkImageProvider(
asyncSnapshot.requireData), asyncSnapshot.requireData),
width: profilePictureWidth, width: profilePictureWidth,
expandable: true,
editable: false, editable: false,
fileNameController: TextEditingController(), fileNameController: TextEditingController(),
userSelectedfile: file, userSelectedfile: file,

View File

@@ -211,6 +211,7 @@ class _MihBusinessQrCodeState extends State<MihBusinessQrCode> {
imageFile: CachedNetworkImageProvider( imageFile: CachedNetworkImageProvider(
asyncSnapshot.requireData), asyncSnapshot.requireData),
width: profilePictureWidth, width: profilePictureWidth,
expandable: true,
editable: false, editable: false,
fileNameController: TextEditingController(), fileNameController: TextEditingController(),
userSelectedfile: file, userSelectedfile: file,

View File

@@ -189,6 +189,7 @@ class _MihMyBusinessUserState extends State<MihMyBusinessUser> {
MihCircleAvatar( MihCircleAvatar(
imageFile: mzansiProfileProvider.userProfilePicture, imageFile: mzansiProfileProvider.userProfilePicture,
width: 150, width: 150,
expandable: true,
editable: false, editable: false,
fileNameController: fileNameController, fileNameController: fileNameController,
userSelectedfile: userPicFile, userSelectedfile: userPicFile,

View File

@@ -343,6 +343,7 @@ class _MihEditPersonalProfileWindowState
? MemoryImage(newSelectedProPic!.bytes!) ? MemoryImage(newSelectedProPic!.bytes!)
: mzansiProfileProvider.userProfilePicture, : mzansiProfileProvider.userProfilePicture,
width: 150, width: 150,
expandable: false,
editable: true, editable: true,
fileNameController: proPicController, fileNameController: proPicController,
userSelectedfile: newSelectedProPic, userSelectedfile: newSelectedProPic,

View File

@@ -160,6 +160,7 @@ class _MihPersonalProfileState extends State<MihPersonalProfile> {
MihCircleAvatar( MihCircleAvatar(
imageFile: mzansiProfileProvider.userProfilePicture, imageFile: mzansiProfileProvider.userProfilePicture,
width: 150, width: 150,
expandable: true,
editable: false, editable: false,
fileNameController: proPicController, fileNameController: proPicController,
userSelectedfile: newSelectedProPic, userSelectedfile: newSelectedProPic,

View File

@@ -74,6 +74,7 @@ class _MihPersonalProfileViewState extends State<MihPersonalProfileView> {
imageFile: CachedNetworkImageProvider( imageFile: CachedNetworkImageProvider(
asyncSnapshot.requireData), asyncSnapshot.requireData),
width: profilePictureWidth, width: profilePictureWidth,
expandable: true,
editable: false, editable: false,
fileNameController: TextEditingController(), fileNameController: TextEditingController(),
userSelectedfile: file, userSelectedfile: file,

View File

@@ -314,6 +314,7 @@ class _PatientInfoState extends State<PatientInfo> {
imageFile: imageFile:
patientManagerProvider.selectedPatientProfilePicture, patientManagerProvider.selectedPatientProfilePicture,
width: 160, width: 160,
expandable: true,
editable: false, editable: false,
fileNameController: null, fileNameController: null,
userSelectedfile: null, userSelectedfile: null,