profile page with HomeCubit

This commit is contained in:
mohammad
2024-07-24 16:03:22 +03:00
parent 1044775066
commit 69b901afed
10 changed files with 153 additions and 159 deletions
@@ -1,11 +1,10 @@
import 'dart:convert';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_event.dart';
import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_state.dart';
import 'package:syncrow_app/features/menu/bloc/profile_bloc/region_model.dart';
@@ -16,6 +15,7 @@ import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
bool isSaving = false;
bool editName = false;
final FocusNode focusNode = FocusNode();
@@ -24,7 +24,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
String timeZoneSelected = '';
String regionSelected = '';
final TextEditingController searchController = TextEditingController();
final TextEditingController nameController = TextEditingController(text: '${AuthCubit.user!.firstName} ${AuthCubit.user!.lastName}');
final TextEditingController nameController = TextEditingController(text: '${HomeCubit.user!.firstName} ${HomeCubit.user!.lastName}');
List<TimeZone>? timeZoneList;
List<RegionModel>? regionList;
@@ -42,14 +42,30 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
on<SelectRegionEvent>(selectRegion);
}
Uint8List? decodeBase64Image(String? base64String) {
if (base64String != null) {
final startIndex = base64String.indexOf('base64,') + 7;
final pureBase64String = base64String.substring(startIndex);
return base64.decode(pureBase64String);
Future<void> saveName(SaveNameEvent event, Emitter<ProfileState> emit) async {
if (_validateInputs()) return;
try {
add(const ChangeNameEvent(value: false));
isSaving = true;
emit(LoadingInitialState());
final fullName = nameController.text;
final nameParts = fullName.split(' ');
final firstName = nameParts[0];
final lastName = nameParts.length > 1 ? nameParts[1] : '';
var response = await ProfileApi.saveName(firstName: firstName, lastName: lastName);
add(InitialProfileEvent());
final homeCubit = event.context.read<HomeCubit>();
await homeCubit.fetchUserInfo();
Navigator.of(event.context).pop(true);
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveState());
} catch (_) {
// Handle the error
} finally {
isSaving = false;
}
return null;
}
void _changeName(ChangeNameEvent event, Emitter<ProfileState> emit) {
emit(LoadingInitialState());
editName = event.value!;
@@ -66,7 +82,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
void _fetchUserInfo(InitialProfileEvent event, Emitter<ProfileState> emit) async {
try {
emit(LoadingInitialState());
AuthCubit.user = await ProfileApi.fetchUserInfo(AuthCubit.user!.uuid);
HomeCubit.user = await ProfileApi().fetchUserInfo(HomeCubit.user!.uuid);
emit(SaveState());
} catch (e) {
emit(FailedState(errorMessage: e.toString()));
@@ -212,28 +228,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
);
}
Future<void> saveName(SaveNameEvent event, Emitter<ProfileState> emit) async {
if (_validateInputs()) return;
try {
add(const ChangeNameEvent(value: false));
isSaving = true;
emit(LoadingInitialState());
final fullName = nameController.text;
final nameParts = fullName.split(' ');
final firstName = nameParts[0];
final lastName = nameParts.length > 1 ? nameParts[1] : '';
var response = await ProfileApi.saveName(firstName: firstName, lastName: lastName);
add(InitialProfileEvent());
AuthCubit.get(event.context).fetchUserInfo();
Navigator.of(event.context).pop(true);
CustomSnackBar.displaySnackBar('Save Successfully');
emit(SaveState());
} catch (_) {
// Handle the error
} finally {
isSaving = false;
}
}
bool _validateInputs() {
if (nameController.text.length < 2) {
@@ -1,98 +1,90 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/menu/view/widgets/profile/profile_view.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
class ProfileTab extends StatelessWidget {
final String? name;
const ProfileTab({super.key, this.name});
const ProfileTab({super.key,});
@override
Widget build(BuildContext context) {
return BlocBuilder<AuthCubit, AuthState>(
return BlocBuilder<HomeCubit, HomeState>(
builder: (context, state) {
final user = AuthCubit.user;
Uint8List? imageBytes;
if (user!.profilePicture != null) {
final base64String = user.profilePicture!;
final startIndex = base64String.indexOf('base64,') + 7;
final pureBase64String = base64String.substring(startIndex);
imageBytes = base64.decode(pureBase64String);
}
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: InkWell(
onTap: () {
Navigator.of(context)
.push(
MaterialPageRoute(
builder: (context) => const ProfileView(),
),
)
.then((result) {
if (result == true) {
context.read<AuthCubit>().fetchUserInfo();
}
});
},
child: Stack(
return _buildProfileContent(context );
},
);
}
Widget _buildProfileContent(BuildContext context) {
final homeCubit = context.read<HomeCubit>();
return Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: InkWell(
onTap: () {
Navigator.of(context)
.push(
MaterialPageRoute(
builder: (context) => const ProfileView(),
),
).then((result) {
context.read<HomeCubit>().fetchUserInfo();
});
},
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 20),
DefaultContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
const SizedBox(height: 20),
DefaultContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Row(
children: [
BodyMedium(
text: '${user.firstName!} ',
fontWeight: FontWeight.bold,
),
BodyMedium(
text: user.lastName!,
fontWeight: FontWeight.bold,
),
],
BodyMedium(
text: '${HomeCubit.user!.firstName ?? ''} ',
fontWeight: FontWeight.bold,
),
BodyMedium(
text: HomeCubit.user!.lastName ?? '',
fontWeight: FontWeight.bold,
),
const BodySmall(text: "Syncrow Account"),
],
),
),
],
),
Positioned(
right: 20,
top: 0,
child: CircleAvatar(
radius: 38,
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 37,
backgroundColor: Colors.grey,
child: ClipOval(
child: Image.memory(
imageBytes!,
fit: BoxFit.cover,
width: 110, // You can adjust the width and height as needed
height: 110,
)),
),
const BodySmall(text: "Syncrow Account"),
],
),
),
],
),
),
);
},
Positioned(
right: 20,
top: 0,
child: CircleAvatar(
radius: 38,
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 37,
backgroundColor: Colors.grey,
child: ClipOval(
child: HomeCubit.user?.profilePicture != null
? Image.memory(
HomeCubit.user!.profilePicture!,
fit: BoxFit.cover,
width: 110,
height: 110,
)
: Icon(Icons.person, size: 70), // Fallback if no image
),
),
),
),
],
),
),
);
}
}
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart';
import 'package:syncrow_app/features/auth/bloc/auth_cubit.dart';
import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_bloc.dart';
import 'package:syncrow_app/features/menu/bloc/profile_bloc/profile_event.dart';
@@ -18,14 +19,12 @@ class ProfileView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (BuildContext context) => ProfileBloc()..add(InitialProfileEvent()),
child: BlocConsumer<ProfileBloc, ProfileState>(
listener: (context, state) {},
builder: (context, state) {
final profileBloc = BlocProvider.of<ProfileBloc>(context);
Uint8List? imageBytes = profileBloc.decodeBase64Image(AuthCubit.user!.profilePicture);
return DefaultScaffold(
title: 'Syncrow Account',
child:
@@ -54,10 +53,10 @@ class ProfileView extends StatelessWidget {
: FileImage(profileBloc.image!),
child: profileBloc.image != null
? null
:imageBytes != null
:HomeCubit.user!.profilePicture != null
? ClipOval(
child: Image.memory(
imageBytes,
HomeCubit.user!.profilePicture!,
fit: BoxFit.cover,
width: 110,
height: 110,
@@ -121,11 +120,8 @@ class ProfileView extends StatelessWidget {
vertical: 5,
),
child:
BlocBuilder<AuthCubit, AuthState>(
builder: (context, state) {
final user = AuthCubit.user;
return Column(
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
@@ -137,17 +133,16 @@ class ProfileView extends StatelessWidget {
builder: (context) => const RegionPage(),
),
).then((result) {
context.read<AuthCubit>().fetchUserInfo();
profileBloc.add(InitialProfileEvent());
});
},
child: Padding(
child: Padding(
padding: const EdgeInsets.only(top: 20, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const BodyMedium(text: 'Region '),
Flexible(child: BodyMedium(text: user!.regionName??'No Region')),
Flexible(child: BodyMedium(text: HomeCubit.user!.regionName ?? 'No Region')),
],
),
),
@@ -164,24 +159,25 @@ class ProfileView extends StatelessWidget {
builder: (context) => const TimeZoneScreenPage(),
),
).then((result) {
context.read<AuthCubit>().fetchUserInfo();
profileBloc.add(InitialProfileEvent());
});
},
child: Padding(
child: Padding(
padding: const EdgeInsets.only(top: 15, bottom: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const BodyMedium(text: 'Time Zone '),
Flexible(
child: BodyMedium(text: user.timeZone??"No Time Zone"),
child: BodyMedium(text: HomeCubit.user!.timeZone ?? "No Time Zone"),
),
],
),
),
),
],
);}),
)
),
],
),
@@ -61,8 +61,7 @@ class RegionPage extends StatelessWidget {
return InkWell(
onTap: () {
profileBloc.add(SelectRegionEvent(
val: regionList[index].id,
context: context));
val: regionList[index].id, context: context));
},
child: Padding(
padding: const EdgeInsets.all(10.0),