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(
imageFile: imagePreview,
width: 50,
expandable: true,
editable: false,
fileNameController: _fileNameController,
userSelectedfile: file,

View File

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

View File

@@ -2,13 +2,17 @@ import 'dart:io';
import 'package:file_picker/file_picker.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/mih_package_components/mih_icons.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 {
final ImageProvider<Object>? imageFile;
final double width;
final bool expandable;
final bool editable;
final TextEditingController? fileNameController;
final onChange;
@@ -19,6 +23,7 @@ class MihCircleAvatar extends StatefulWidget {
super.key,
required this.imageFile,
required this.width,
required this.expandable,
required this.editable,
required this.fileNameController,
required this.userSelectedfile,
@@ -35,23 +40,30 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
late ImageProvider<Object>? imagePreview;
ImageProvider<Object>? getAvatar() {
// Color dark = const Color(0XFF3A4454);
if (widget.imageFile == 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 {
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
void initState() {
super.initState();
@@ -62,111 +74,121 @@ class _MihCircleAvatarState extends State<MihCircleAvatar> {
@override
Widget build(BuildContext context) {
return Container(
// color: Colors.white,
alignment: Alignment.center,
width: widget.width,
height: widget.width,
child: Stack(
return GestureDetector(
onTap: widget.expandable
? () {
KenLogger.success("Avatar tapped");
expandAvatar();
}
: null,
child: Container(
alignment: Alignment.center,
children: [
Visibility(
visible: imagePreview != null,
child: Positioned(
right: widget.width * 0.03,
child: CircleAvatar(
radius: widget.width / 2.2,
backgroundColor: widget.backgroundColor,
backgroundImage: imagePreview,
width: widget.width,
height: widget.width,
child: Stack(
alignment: Alignment.center,
children: [
Visibility(
visible: imagePreview != null,
child: Positioned(
right: widget.width * 0.03,
child: CircleAvatar(
radius: widget.width / 2.2,
backgroundColor: widget.backgroundColor,
backgroundImage: imagePreview,
),
),
),
),
Visibility(
visible: imagePreview != null,
child: Icon(
size: widget.width,
MihIcons.mihRing,
color: widget.frameColor,
Visibility(
visible: imagePreview != null,
child: Icon(
size: widget.width,
MihIcons.mihRing,
color: widget.frameColor,
),
),
),
Visibility(
visible: imagePreview == null,
child: Icon(
MihIcons.iDontKnow,
size: widget.width,
color: widget.frameColor,
Visibility(
visible: imagePreview == null,
child: Icon(
MihIcons.iDontKnow,
size: widget.width,
color: widget.frameColor,
),
),
),
Visibility(
visible: widget.editable,
child: Positioned(
bottom: 0,
right: 0,
child: IconButton.filled(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all<Color>(
MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
Visibility(
visible: widget.editable,
child: Positioned(
bottom: 0,
right: 0,
child: IconButton.filled(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all<Color>(
MihColors.getGreenColor(
MzansiInnovationHub.of(context)!.theme.mode ==
"Dark"),
),
),
),
onPressed: () async {
try {
FilePickerResult? result =
await FilePicker.platform.pickFiles(
type: FileType.image,
);
// print("Here 1");
if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
"Web") {
// print("Here 2");
if (result == null) return;
// print("Here 3");
PlatformFile? selectedFile = result.files.first;
setState(() {
// 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,
);
onPressed: () async {
try {
FilePickerResult? result =
await FilePicker.platform.pickFiles(
type: FileType.image,
);
// print("Here 1");
if (MzansiInnovationHub.of(context)!
.theme
.getPlatform() ==
"Web") {
// print("Here 2");
if (result == null) return;
// print("Here 3");
PlatformFile? selectedFile = result.files.first;
setState(() {
widget.onChange(androidFile);
imagePreview = FileImage(file);
// print("Here 4");
widget.onChange(selectedFile);
// print("Here 5");
imagePreview = MemoryImage(selectedFile.bytes!);
});
setState(() {
widget.fileNameController!.text =
file.path.split('/').last;
widget.fileNameController!.text = selectedFile.name;
});
} else {
print("here in else");
// User canceled the picker
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(() {
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(
imageFile: widget.imageFile,
width: profilePictureWidth,
expandable: false,
editable: false,
fileNameController: TextEditingController(),
userSelectedfile: null,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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