elCaribe app - customization and branding
This commit is contained in:
555
news-app/lib/ui/screens/Profile/ProfileScreen.dart
Normal file
555
news-app/lib/ui/screens/Profile/ProfileScreen.dart
Normal file
@@ -0,0 +1,555 @@
|
||||
import 'dart:io';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:in_app_review/in_app_review.dart';
|
||||
import 'package:news/app/app.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/cubits/Auth/authCubit.dart';
|
||||
import 'package:news/cubits/Auth/deleteUserCubit.dart';
|
||||
import 'package:news/cubits/Auth/registerTokenCubit.dart';
|
||||
import 'package:news/cubits/Author/authorCubit.dart';
|
||||
import 'package:news/cubits/appLocalizationCubit.dart';
|
||||
import 'package:news/cubits/appSystemSettingCubit.dart';
|
||||
import 'package:news/cubits/languageJsonCubit.dart';
|
||||
import 'package:news/cubits/otherPagesCubit.dart';
|
||||
import 'package:news/cubits/settingCubit.dart';
|
||||
import 'package:news/data/repositories/Auth/authLocalDataSource.dart';
|
||||
import 'package:news/ui/screens/Profile/Widgets/customAlertDialog.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:news/ui/widgets/customAppBar.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/utils/constant.dart';
|
||||
import 'package:news/utils/internetConnectivity.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:news/cubits/themeCubit.dart';
|
||||
import 'package:news/ui/styles/appTheme.dart';
|
||||
import 'package:news/ui/widgets/SnackBarWidget.dart';
|
||||
|
||||
class ProfileScreen extends StatefulWidget {
|
||||
const ProfileScreen({super.key});
|
||||
|
||||
@override
|
||||
ProfileScreenState createState() => ProfileScreenState();
|
||||
|
||||
static Route route(RouteSettings routeSettings) {
|
||||
return CupertinoPageRoute(builder: (_) => const ProfileScreen());
|
||||
}
|
||||
}
|
||||
|
||||
class ProfileScreenState extends State<ProfileScreen> {
|
||||
File? image;
|
||||
String? name, mobile, email, profile;
|
||||
TextEditingController? nameC, monoC, emailC = TextEditingController();
|
||||
AuthLocalDataSource authLocalDataSource = AuthLocalDataSource();
|
||||
bool isEditMono = false, isEditEmail = false, isAuthor = false;
|
||||
final FirebaseAuth _auth = FirebaseAuth.instance;
|
||||
final InAppReview _inAppReview = InAppReview.instance;
|
||||
late AuthorStatus authorStatus;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
getOtherPagesData();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
getOtherPagesData() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<OtherPageCubit>().getOtherPage(langId: context.read<AppLocalizationCubit>().state.id);
|
||||
});
|
||||
}
|
||||
|
||||
Widget pagesBuild() {
|
||||
return BlocBuilder<OtherPageCubit, OtherPageState>(builder: (context, state) {
|
||||
if (state is OtherPageFetchSuccess) {
|
||||
return ScrollConfiguration(
|
||||
behavior: GlobalScrollBehavior(),
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.zero,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: state.otherPage.length,
|
||||
itemBuilder: ((context, index) =>
|
||||
setDrawerItem(state.otherPage[index].title!, Icons.info_rounded, false, true, false, 8, image: state.otherPage[index].image!, desc: state.otherPage[index].pageContent))),
|
||||
);
|
||||
} else {
|
||||
//state is OtherPageFetchInProgress || state is OtherPageInitial || state is OtherPageFetchFailure
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
switchTheme(bool value) async {
|
||||
if (value) {
|
||||
if (await InternetConnectivity.isNetworkAvailable()) {
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
|
||||
context.read<ThemeCubit>().changeTheme(AppTheme.Dark);
|
||||
UiUtils.setUIOverlayStyle(appTheme: AppTheme.Dark);
|
||||
//for non-appbar screens
|
||||
} else {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'internetmsg'), context);
|
||||
}
|
||||
} else {
|
||||
if (await InternetConnectivity.isNetworkAvailable()) {
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
|
||||
context.read<ThemeCubit>().changeTheme(AppTheme.Light);
|
||||
UiUtils.setUIOverlayStyle(appTheme: AppTheme.Light);
|
||||
//for non-appbar screens
|
||||
} else {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'internetmsg'), context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool getTheme() {
|
||||
return (context.read<ThemeCubit>().state.appTheme == AppTheme.Dark) ? true : false;
|
||||
}
|
||||
|
||||
bool getNotification() {
|
||||
if (context.read<SettingsCubit>().state.settingsModel!.notification == true) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switchNotification(bool value) {
|
||||
if (!value) {
|
||||
FirebaseMessaging.instance.deleteToken().then((value) async {
|
||||
context.read<RegisterTokenCubit>().registerToken(fcmId: '', context: context);
|
||||
});
|
||||
} else {
|
||||
FirebaseMessaging.instance.getToken().then((value) async {
|
||||
context.read<RegisterTokenCubit>().registerToken(fcmId: value!, context: context);
|
||||
context.read<SettingsCubit>().changeFcmToken(value);
|
||||
});
|
||||
}
|
||||
|
||||
context.read<SettingsCubit>().changeNotification(value);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
//set drawer item list
|
||||
Widget setDrawerItem(String title, IconData? icon, bool isTrailing, bool isNavigate, bool isSwitch, int id, {String? image, String? desc, bool isDeleteAcc = false}) {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: Container(
|
||||
height: 30,
|
||||
width: 30,
|
||||
padding: EdgeInsets.all(3),
|
||||
decoration: BoxDecoration(shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(7), color: borderColor.withOpacity(0.2)),
|
||||
child: (image != null && image != "")
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
child: Image.network(
|
||||
image,
|
||||
width: 20,
|
||||
height: 20,
|
||||
color: (image.contains("png")) ? UiUtils.getColorScheme(context).primaryContainer : null,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
return Icon(icon);
|
||||
},
|
||||
),
|
||||
)
|
||||
: Icon(icon, size: 20)),
|
||||
iconColor: (isDeleteAcc) ? (context.read<ThemeCubit>().state.appTheme == AppTheme.Dark ? darkIconColor : iconColor) : UiUtils.getColorScheme(context).primaryContainer,
|
||||
trailing: (isTrailing)
|
||||
? SizedBox(
|
||||
height: 45,
|
||||
width: 55,
|
||||
child: FittedBox(
|
||||
fit: BoxFit.fill,
|
||||
child: Switch.adaptive(
|
||||
onChanged: (id == 0) ? switchTheme : switchNotification,
|
||||
value: (id == 0) ? getTheme() : getNotification(),
|
||||
activeColor: Theme.of(context).primaryColor,
|
||||
activeTrackColor: Theme.of(context).primaryColor,
|
||||
inactiveThumbColor: Colors.grey,
|
||||
inactiveTrackColor: Colors.grey)))
|
||||
: const SizedBox.shrink(),
|
||||
title: CustomTextLabel(
|
||||
text: title,
|
||||
textStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium
|
||||
?.copyWith(color: (isDeleteAcc) ? (context.read<ThemeCubit>().state.appTheme == AppTheme.Dark ? darkIconColor : iconColor) : UiUtils.getColorScheme(context).primaryContainer)),
|
||||
onTap: () {
|
||||
if (isNavigate) {
|
||||
switch (id) {
|
||||
case 2:
|
||||
Navigator.of(context).pushNamed(Routes.languageList, arguments: {"from": "profile"});
|
||||
break;
|
||||
case 3:
|
||||
Navigator.of(context).pushNamed(Routes.bookmark);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
Navigator.of(context).pushNamed(Routes.addNews, arguments: {"isEdit": false, "from": "profile"});
|
||||
break;
|
||||
case 6:
|
||||
Navigator.of(context).pushNamed(Routes.manageUserNews);
|
||||
break;
|
||||
case 7:
|
||||
Navigator.of(context).pushNamed(Routes.managePref, arguments: {"from": 1});
|
||||
break;
|
||||
case 8:
|
||||
Navigator.of(context).pushNamed(Routes.privacy, arguments: {"from": "setting", "title": title, "desc": desc});
|
||||
break;
|
||||
case 9:
|
||||
_openStoreListing();
|
||||
break;
|
||||
case 10:
|
||||
String str = "$appName\n\n${context.read<AppConfigurationCubit>().getShareAppText()}\n\n${context.read<AppConfigurationCubit>().getAndroidAppLink()}\n";
|
||||
bool isIOSAppLive = context.read<AppConfigurationCubit>().getiOSAppLink()?.trim().isNotEmpty ?? false;
|
||||
if (isIOSAppLive) str += "\n\n${context.read<AppConfigurationCubit>().getiOSAppLink()}";
|
||||
Share.share(str, sharePositionOrigin: Rect.fromLTWH(0, 0, MediaQuery.of(context).size.width, MediaQuery.of(context).size.height / 2));
|
||||
break;
|
||||
case 12:
|
||||
deleteAccount();
|
||||
break;
|
||||
case 13:
|
||||
Navigator.of(context).pushNamed(Routes.editUserProfile, arguments: {'from': 'profile'});
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
logOutDialog() async {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(builder: (BuildContext context, StateSetter setStater) {
|
||||
return CustomAlertDialog(
|
||||
isForceAppUpdate: false,
|
||||
context: context,
|
||||
yesButtonText: 'yesLbl',
|
||||
yesButtonTextPostfix: 'logoutLbl',
|
||||
noButtonText: 'noLbl',
|
||||
imageName: 'logout',
|
||||
titleWidget: CustomTextLabel(
|
||||
text: 'logoutLbl', textStyle: Theme.of(this.context).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w500, color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
messageText: 'logoutTxt',
|
||||
onYESButtonPressed: () async {
|
||||
UiUtils.userLogOut(contxt: context);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//set Delete dialogue
|
||||
deleteAccount() async {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(builder: (BuildContext context, StateSetter setStater) {
|
||||
return CustomAlertDialog(
|
||||
context: context,
|
||||
isForceAppUpdate: false,
|
||||
yesButtonText: (_auth.currentUser != null) ? 'yesLbl' : 'logoutLbl',
|
||||
yesButtonTextPostfix: (_auth.currentUser != null) ? 'deleteTxt' : '',
|
||||
noButtonText: (_auth.currentUser != null) ? 'noLbl' : 'cancelBtn',
|
||||
imageName: 'deleteAccount',
|
||||
titleWidget: (_auth.currentUser != null)
|
||||
? CustomTextLabel(
|
||||
text: 'deleteAcc', textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w800, color: UiUtils.getColorScheme(context).primaryContainer))
|
||||
: CustomTextLabel(
|
||||
text: 'deleteAlertTitle', textStyle: Theme.of(context).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.w800, color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
messageText: (_auth.currentUser != null) ? 'deleteConfirm' : 'deleteRelogin',
|
||||
onYESButtonPressed: () async {
|
||||
(_auth.currentUser != null) ? proceedToDeleteProfile() : askToLoginAgain();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
askToLoginAgain() {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'loginReqMsg'), context);
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(Routes.login, (route) => false);
|
||||
}
|
||||
|
||||
proceedToDeleteProfile() async {
|
||||
//delete user from firebase
|
||||
try {
|
||||
await _auth.currentUser!.delete().then((value) {
|
||||
//delete user prefs from App-local
|
||||
context.read<DeleteUserCubit>().deleteUser().then((value) {
|
||||
showSnackBar(value["message"], context);
|
||||
for (int i = 0; i < AuthProviders.values.length; i++) {
|
||||
if (AuthProviders.values[i].name == context.read<AuthCubit>().getType()) {
|
||||
context.read<AuthCubit>().signOut(AuthProviders.values[i]).then((value) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(Routes.login, (route) => false);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} on FirebaseAuthException catch (error) {
|
||||
if (error.code == "requires-recent-login") {
|
||||
for (int i = 0; i < AuthProviders.values.length; i++) {
|
||||
if (AuthProviders.values[i].name == context.read<AuthCubit>().getType()) {
|
||||
context.read<AuthCubit>().signOut(AuthProviders.values[i]).then((value) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(Routes.login, (route) => false);
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw showSnackBar('${error.message}', context);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
Future<void> _openStoreListing() => _inAppReview.openStoreListing(appStoreId: context.read<AppConfigurationCubit>().getAppstoreId(), microsoftStoreId: 'microsoftStoreId');
|
||||
|
||||
Widget setHeader() {
|
||||
return BlocBuilder<AuthCubit, AuthState>(builder: (context, authState) {
|
||||
if (authState is Authenticated && context.read<AuthCubit>().getUserId() != "0") {
|
||||
isAuthor = (authState.authModel.isAuthor == 1);
|
||||
authorStatus = ((authState.authModel.authorDetails != null) ? authState.authModel.authorDetails?.status : AuthorStatus.rejected)!;
|
||||
return Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 15.0, end: 15.0, top: 15.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsetsDirectional.only(start: 20.0, end: 20.0, top: 10),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15.0), color: Theme.of(context).colorScheme.surface),
|
||||
child: Row(crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[
|
||||
CircleAvatar(
|
||||
radius: 34,
|
||||
backgroundColor: Colors.transparent,
|
||||
child: ClipOval(
|
||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||
child: (authState.authModel.profile != null && authState.authModel.profile.toString().trim().isNotEmpty)
|
||||
? Image.network(
|
||||
authState.authModel.profile!,
|
||||
fit: BoxFit.fill,
|
||||
width: 80,
|
||||
height: 80,
|
||||
filterQuality: FilterQuality.high,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
return const Icon(Icons.person);
|
||||
},
|
||||
)
|
||||
: Icon(Icons.person, color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.6,
|
||||
child: Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 5),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
if (authState.authModel.name != null && authState.authModel.name != "")
|
||||
CustomTextLabel(
|
||||
text: authState.authModel.name!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textStyle: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w800, color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
const SizedBox(height: 3),
|
||||
if (authState.authModel.mobile != null && authState.authModel.mobile!.trim().isNotEmpty)
|
||||
CustomTextLabel(
|
||||
text: authState.authModel.mobile!, textStyle: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7))),
|
||||
const SizedBox(height: 3),
|
||||
if (authState.authModel.email != null && authState.authModel.email != "")
|
||||
CustomTextLabel(
|
||||
text: authState.authModel.email!,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textStyle: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer.withOpacity(0.7))),
|
||||
BlocConsumer<AuthorCubit, AuthorState>(
|
||||
listener: (context, state) {
|
||||
if (state is AuthorRequestSent) showSnackBar(state.responseMessage, context);
|
||||
},
|
||||
builder: (context, state) {
|
||||
return buildAuthorButton(context, state);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
|
||||
//For Guest User
|
||||
Container(
|
||||
margin: const EdgeInsets.all(15),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(shape: BoxShape.circle, border: Border.all(color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
alignment: Alignment.center,
|
||||
child: Icon(Icons.person, size: 25.0, color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
Expanded(child: setGuestText())
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Widget buildAuthorButton(BuildContext context, AuthorState state) {
|
||||
//check if user is author already
|
||||
if (isAuthor || authorStatus == AuthorStatus.approved || state is AuthorApproved) {
|
||||
return IntrinsicWidth(
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(color: backgroundColor, borderRadius: BorderRadius.circular(5), border: Border.all(color: authorApprovedColor)),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.verified_outlined, size: 18, color: authorApprovedColor),
|
||||
SizedBox(width: 6),
|
||||
const CustomTextLabel(text: 'authorLbl', textStyle: TextStyle(color: authorApprovedColor, fontWeight: FontWeight.w600)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (authorStatus == AuthorStatus.pending || state is AuthorRequestSent) {
|
||||
return IntrinsicWidth(
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(color: backgroundColor, borderRadius: BorderRadius.circular(8), border: Border.all(color: authorReviewColor)),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: const [
|
||||
Icon(Icons.info_outline, size: 18, color: authorReviewColor),
|
||||
SizedBox(width: 6),
|
||||
CustomTextLabel(text: 'authorReviewPendingLbl', textStyle: TextStyle(color: authorReviewColor, fontWeight: FontWeight.w500)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (authorStatus == AuthorStatus.rejected || state is AuthorInitial) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
//redirect to update profile screen
|
||||
Navigator.of(context).pushNamed(Routes.editUserProfile, arguments: {'from': 'becomeAuthor'});
|
||||
},
|
||||
child: Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(color: backgroundColor, borderRadius: BorderRadius.circular(5), border: Border.all(color: authorRequestColor)),
|
||||
child: const CustomTextLabel(text: 'becomeAuthorLbl', textStyle: TextStyle(color: authorRequestColor, fontWeight: FontWeight.w500))),
|
||||
);
|
||||
}
|
||||
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
Widget setGuestText() {
|
||||
return BlocBuilder<LanguageJsonCubit, LanguageJsonState>(
|
||||
builder: (context, langState) {
|
||||
return RichText(
|
||||
text: TextSpan(
|
||||
text: UiUtils.getTranslatedLabel(context, 'plzLbl'),
|
||||
style: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, overflow: TextOverflow.ellipsis),
|
||||
children: <TextSpan>[
|
||||
TextSpan(
|
||||
text: " ${UiUtils.getTranslatedLabel(context, 'loginBtn')} ",
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(color: Theme.of(context).primaryColor, fontWeight: FontWeight.w600, overflow: TextOverflow.ellipsis),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
setState(() {
|
||||
Navigator.of(context).pushReplacementNamed(Routes.login);
|
||||
});
|
||||
});
|
||||
}),
|
||||
TextSpan(
|
||||
text: "${UiUtils.getTranslatedLabel(context, 'firstAccLbl')} ", style: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
TextSpan(
|
||||
text: UiUtils.getTranslatedLabel(context, 'allFunLbl'),
|
||||
style: Theme.of(context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, overflow: TextOverflow.ellipsis))
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget setBody() {
|
||||
return Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 15.0, end: 15.0, top: 15.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsetsDirectional.only(start: 20.0, end: 20.0),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(15.0), color: Theme.of(context).colorScheme.surface),
|
||||
child: ScrollConfiguration(
|
||||
behavior: GlobalScrollBehavior(),
|
||||
child: BlocBuilder<AuthCubit, AuthState>(
|
||||
builder: (context, state) {
|
||||
return ListView(
|
||||
padding: const EdgeInsetsDirectional.only(top: 10.0),
|
||||
shrinkWrap: true,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
children: <Widget>[
|
||||
if (context.read<AuthCubit>().getUserId() != "0") setDrawerItem('editProfile', Icons.edit_outlined, false, true, false, 13),
|
||||
setDrawerItem('darkModeLbl', Icons.swap_horizontal_circle, true, false, true, 0),
|
||||
setDrawerItem('notificationLbl', Icons.notifications_rounded, true, false, true, 1),
|
||||
setDrawerItem('changeLang', Icons.g_translate_rounded, false, true, false, 2),
|
||||
Divider(thickness: 2),
|
||||
if (context.read<AuthCubit>().getUserId() != "0") setDrawerItem('bookmarkLbl', Icons.bookmarks_rounded, false, true, false, 3),
|
||||
// if (context.read<AuthCubit>().getUserId() != "0") setDrawerItem('notificationLbl', Icons.notifications, false, true, false, 4),
|
||||
if (context.read<AuthCubit>().getUserId() != "0" && isAuthor)
|
||||
// context.read<AuthCubit>().getRole() != "0")
|
||||
setDrawerItem('createNewsLbl', Icons.add_box_rounded, false, true, false, 5),
|
||||
if (context.read<AuthCubit>().getUserId() != "0" && isAuthor)
|
||||
// context.read<AuthCubit>().getRole() != "0")
|
||||
setDrawerItem('manageNewsLbl', Icons.edit_document, false, true, false, 6),
|
||||
if (context.read<AuthCubit>().getUserId() != "0") setDrawerItem('managePreferences', Icons.thumbs_up_down_rounded, false, true, false, 7),
|
||||
if (context.read<AuthCubit>().getUserId() != "0") Divider(thickness: 2),
|
||||
pagesBuild(),
|
||||
setDrawerItem('rateUs', Icons.stars_sharp, false, true, false, 9),
|
||||
setDrawerItem('shareApp', Icons.share_rounded, false, true, false, 10),
|
||||
if (context.read<AuthCubit>().getUserId() != "0") setDrawerItem('deleteAcc', Icons.delete_forever_rounded, false, true, false, 12, isDeleteAcc: true),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
height: 45,
|
||||
isBackBtn: false,
|
||||
label: 'myProfile',
|
||||
isConvertText: true,
|
||||
actionWidget: [if (context.read<AuthCubit>().getUserId() != "0") logoutButton()],
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
SingleChildScrollView(
|
||||
padding: const EdgeInsetsDirectional.only(top: 15.0, bottom: 10.0),
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: <Widget>[setHeader(), setBody()])),
|
||||
],
|
||||
)));
|
||||
}
|
||||
|
||||
Widget logoutButton() {
|
||||
return GestureDetector(
|
||||
onTap: () => logOutDialog(),
|
||||
child: Container(
|
||||
margin: EdgeInsetsDirectional.only(end: 15, top: 12, bottom: 12),
|
||||
height: 30,
|
||||
width: 30,
|
||||
padding: EdgeInsets.all(3),
|
||||
decoration: BoxDecoration(shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(7), color: Colors.transparent, border: Border.all(width: 2, color: borderColor.withOpacity(0.3))),
|
||||
child: Icon(Icons.power_settings_new_rounded, color: UiUtils.getColorScheme(context).primaryContainer, size: 20)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:news/ui/screens/auth/Widgets/svgPictureWidget.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
|
||||
class CustomAlertDialog extends StatelessWidget {
|
||||
final BuildContext context;
|
||||
final String yesButtonText;
|
||||
final String yesButtonTextPostfix;
|
||||
final String noButtonText;
|
||||
final String imageName;
|
||||
final Widget titleWidget;
|
||||
final String messageText;
|
||||
final Function() onYESButtonPressed;
|
||||
final bool isForceAppUpdate;
|
||||
const CustomAlertDialog(
|
||||
{super.key,
|
||||
required this.context,
|
||||
required this.yesButtonText,
|
||||
required this.yesButtonTextPostfix,
|
||||
required this.noButtonText,
|
||||
required this.imageName,
|
||||
required this.titleWidget,
|
||||
required this.messageText,
|
||||
required this.onYESButtonPressed,
|
||||
required this.isForceAppUpdate});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
contentPadding: const EdgeInsets.all(20),
|
||||
backgroundColor: UiUtils.getColorScheme(context).surface,
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0))),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SvgPictureWidget(assetName: imageName),
|
||||
const SizedBox(height: 15),
|
||||
titleWidget,
|
||||
const SizedBox(height: 5),
|
||||
CustomTextLabel(text: messageText, textAlign: TextAlign.center, textStyle: Theme.of(this.context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
],
|
||||
),
|
||||
actionsAlignment: MainAxisAlignment.spaceAround,
|
||||
actionsOverflowButtonSpacing: 15,
|
||||
actions: <Widget>[
|
||||
MaterialButton(
|
||||
minWidth: MediaQuery.of(context).size.width / 3.5,
|
||||
elevation: 0.0,
|
||||
highlightColor: Colors.transparent,
|
||||
color: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4), side: BorderSide(color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
onPressed: () => (isForceAppUpdate) ? exit(0) : Navigator.of(context).pop(false),
|
||||
child: CustomTextLabel(
|
||||
text: noButtonText, textStyle: Theme.of(this.context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.w500)),
|
||||
),
|
||||
MaterialButton(
|
||||
elevation: 0.0,
|
||||
color: UiUtils.getColorScheme(context).primaryContainer,
|
||||
splashColor: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
|
||||
onPressed: onYESButtonPressed,
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: UiUtils.getTranslatedLabel(context, yesButtonText),
|
||||
style: Theme.of(this.context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).surface, fontWeight: FontWeight.w500),
|
||||
children: [
|
||||
const TextSpan(text: " , "),
|
||||
TextSpan(
|
||||
text: UiUtils.getTranslatedLabel(context, yesButtonTextPostfix),
|
||||
style: Theme.of(this.context).textTheme.titleSmall?.copyWith(color: UiUtils.getColorScheme(context).surface, fontWeight: FontWeight.w500))
|
||||
]),
|
||||
)),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
401
news-app/lib/ui/screens/Profile/userProfile.dart
Normal file
401
news-app/lib/ui/screens/Profile/userProfile.dart
Normal file
@@ -0,0 +1,401 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:news/app/routes.dart';
|
||||
import 'package:news/cubits/Auth/authCubit.dart';
|
||||
import 'package:news/cubits/Auth/updateUserCubit.dart';
|
||||
import 'package:news/cubits/Author/authorCubit.dart';
|
||||
import 'package:news/cubits/languageCubit.dart';
|
||||
import 'package:news/data/repositories/Auth/authLocalDataSource.dart';
|
||||
import 'package:news/ui/styles/colors.dart';
|
||||
import 'package:news/ui/widgets/SnackBarWidget.dart';
|
||||
|
||||
import 'package:news/ui/widgets/customAppBar.dart';
|
||||
import 'package:news/ui/widgets/customTextLabel.dart';
|
||||
import 'package:news/utils/uiUtils.dart';
|
||||
import 'package:news/utils/validators.dart';
|
||||
|
||||
class UserProfileScreen extends StatefulWidget {
|
||||
final String from;
|
||||
const UserProfileScreen({super.key, required this.from});
|
||||
|
||||
@override
|
||||
State createState() => UserProfileScreenState();
|
||||
|
||||
static Route route(RouteSettings routeSettings) {
|
||||
Map arguments = routeSettings.arguments as Map;
|
||||
return CupertinoPageRoute(builder: (_) => UserProfileScreen(from: arguments['from'] as String));
|
||||
}
|
||||
}
|
||||
|
||||
class UserProfileScreenState extends State<UserProfileScreen> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
AuthLocalDataSource authLocalDataSource = AuthLocalDataSource();
|
||||
dynamic size;
|
||||
FocusNode nameFocus = FocusNode();
|
||||
FocusNode mobNoFocus = FocusNode();
|
||||
FocusNode emailFocus = FocusNode();
|
||||
FocusNode crntFocus = FocusNode();
|
||||
FocusNode authorBioFocus = FocusNode();
|
||||
FocusNode telegramLinkFocus = FocusNode();
|
||||
FocusNode facebookLinkFocus = FocusNode();
|
||||
FocusNode linkedInLinkFocus = FocusNode();
|
||||
FocusNode whatsappLinkFocus = FocusNode();
|
||||
|
||||
TextEditingController? nameC = TextEditingController(), monoC = TextEditingController(), emailC = TextEditingController();
|
||||
TextEditingController? authorBioC = TextEditingController();
|
||||
TextEditingController? telegramLinkC = TextEditingController();
|
||||
TextEditingController? facebookLinkC = TextEditingController();
|
||||
TextEditingController? whatsappLinkC = TextEditingController();
|
||||
TextEditingController? linkedInLinkC = TextEditingController();
|
||||
String? profile, mobile;
|
||||
bool isEditMono = false, isEditEmail = false, isSaving = false, isThisUserAnAuthor = false;
|
||||
String? updateValue;
|
||||
File? image;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
isThisUserAnAuthor = context.read<AuthCubit>().isAuthor();
|
||||
setControllers();
|
||||
if (widget.from == "login") getLanguageList();
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
setControllers() {
|
||||
nameC = TextEditingController(text: authLocalDataSource.getName());
|
||||
emailC = TextEditingController(text: authLocalDataSource.getEmail());
|
||||
monoC = TextEditingController(text: authLocalDataSource.getMobile());
|
||||
profile = context.read<AuthCubit>().getProfile();
|
||||
if (isThisUserAnAuthor) {
|
||||
authorBioC = TextEditingController(text: (authLocalDataSource.getAuthorBio().isEmpty) ? context.read<AuthCubit>().getAuthorBio() : authLocalDataSource.getAuthorBio());
|
||||
whatsappLinkC =
|
||||
TextEditingController(text: (authLocalDataSource.getAuthorWhatsappLink()!.isEmpty) ? context.read<AuthCubit>().getAuthorWhatsappLink() : authLocalDataSource.getAuthorWhatsappLink());
|
||||
telegramLinkC =
|
||||
TextEditingController(text: (authLocalDataSource.getAuthorTelegramLink()!.isEmpty) ? context.read<AuthCubit>().getAuthorTelegramLink() : authLocalDataSource.getAuthorTelegramLink());
|
||||
linkedInLinkC =
|
||||
TextEditingController(text: (authLocalDataSource.getAuthorLinkedInLink()!.isEmpty) ? context.read<AuthCubit>().getAuthorLinkedInLink() : authLocalDataSource.getAuthorLinkedInLink());
|
||||
facebookLinkC =
|
||||
TextEditingController(text: (authLocalDataSource.getAuthorFacebookLink()!.isEmpty) ? context.read<AuthCubit>().getAuthorFacebookLink() : authLocalDataSource.getAuthorFacebookLink());
|
||||
}
|
||||
}
|
||||
|
||||
getLanguageList() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<LanguageCubit>().getLanguage();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
size = MediaQuery.of(context).size;
|
||||
return Scaffold(appBar: CustomAppBar(height: 45, isBackBtn: (widget.from == "login") ? false : true, label: 'editProfile', isConvertText: true), body: buildProfileFields());
|
||||
}
|
||||
|
||||
onBackPress(bool isTrue) {
|
||||
(widget.from == "login") ? Navigator.of(context).popUntil((route) => route.isFirst) : Navigator.pop(context);
|
||||
}
|
||||
|
||||
setPendingStatusControllerValues() {
|
||||
authorBioC?.clear();
|
||||
whatsappLinkC?.clear();
|
||||
telegramLinkC?.clear();
|
||||
linkedInLinkC?.clear();
|
||||
facebookLinkC?.clear();
|
||||
}
|
||||
|
||||
buildProfileFields() {
|
||||
return PopScope(
|
||||
canPop: (widget.from != "login") ? true : false,
|
||||
onPopInvoked: (bool isTrue) => onBackPress,
|
||||
child: BlocConsumer<UpdateUserCubit, UpdateUserState>(
|
||||
listener: (context, state) {
|
||||
//show snackbar incase of success & failure both
|
||||
if (state is UpdateUserFetchSuccess && state.updatedUser != null) {
|
||||
showSnackBar(UiUtils.getTranslatedLabel(context, 'profileUpdateMsg'), context);
|
||||
isSaving = false;
|
||||
setState(() {});
|
||||
if (widget.from == "becomeAuthor") {
|
||||
//call author request API here
|
||||
context.read<AuthorCubit>().requestToBecomeAuthor();
|
||||
setPendingStatusControllerValues();
|
||||
}
|
||||
if (widget.from == "login") {
|
||||
if (context.read<LanguageCubit>().langList().length > 1) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(Routes.languageList, (route) => false, arguments: {"from": "firstLogin"});
|
||||
} else {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(Routes.managePref, (route) => false, arguments: {"from": 2});
|
||||
}
|
||||
} else {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
if (state is UpdateUserFetchFailure) {
|
||||
isSaving = false;
|
||||
showSnackBar(state.errorMessage, context);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return SingleChildScrollView(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(children: [
|
||||
profileWidget(),
|
||||
setTextField(
|
||||
validatorMethod: (value) => Validators.nameValidation(value!, context),
|
||||
focusNode: nameFocus,
|
||||
nextFocus: (context.read<AuthCubit>().getType() != loginMbl) ? mobNoFocus : emailFocus,
|
||||
textInputAction: TextInputAction.next,
|
||||
keyboardType: TextInputType.name,
|
||||
controller: nameC,
|
||||
hintlbl: UiUtils.getTranslatedLabel(context, 'nameLbl')),
|
||||
SizedBox(height: size.height * 0.03),
|
||||
setMobileNumber(),
|
||||
SizedBox(height: size.height * 0.03),
|
||||
setTextField(
|
||||
validatorMethod: (value) => value!.trim().isEmpty ? null : Validators.emailValidation(value, context),
|
||||
focusNode: emailFocus,
|
||||
nextFocus: isThisUserAnAuthor ? authorBioFocus : null,
|
||||
textInputAction: isThisUserAnAuthor ? TextInputAction.next : TextInputAction.done,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
controller: emailC,
|
||||
isenable: (context.read<AuthCubit>().getType() == loginMbl) ? true : false,
|
||||
hintlbl: UiUtils.getTranslatedLabel(context, 'emailLbl')),
|
||||
SizedBox(height: size.height * 0.05),
|
||||
setAuthorBio(),
|
||||
SizedBox(height: size.height * 0.05),
|
||||
Container(
|
||||
alignment: AlignmentGeometry.centerLeft,
|
||||
padding: EdgeInsetsDirectional.only(start: 20),
|
||||
child: CustomTextLabel(
|
||||
text: 'socialMediaLinksLbl',
|
||||
textStyle: Theme.of(this.context).textTheme.titleMedium?.copyWith(color: UiUtils.getColorScheme(context).primaryContainer, fontWeight: FontWeight.w700))),
|
||||
SizedBox(height: size.height * 0.03),
|
||||
setSocialMediaLink(linkController: telegramLinkC, currFocus: telegramLinkFocus, nextFocus: whatsappLinkFocus, typeForHintText: 'Telegram'),
|
||||
SizedBox(height: size.height * 0.03),
|
||||
setSocialMediaLink(linkController: whatsappLinkC, currFocus: whatsappLinkFocus, nextFocus: facebookLinkFocus, typeForHintText: 'Whatsapp'),
|
||||
SizedBox(height: size.height * 0.03),
|
||||
setSocialMediaLink(linkController: facebookLinkC, currFocus: facebookLinkFocus, nextFocus: linkedInLinkFocus, typeForHintText: 'Facebook'),
|
||||
SizedBox(height: size.height * 0.03),
|
||||
setSocialMediaLink(linkController: linkedInLinkC, currFocus: linkedInLinkFocus, nextFocus: null, typeForHintText: 'LinkedIn'),
|
||||
SizedBox(height: size.height * 0.03),
|
||||
submitBtn(context)
|
||||
])));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget setAuthorBio() {
|
||||
return Container(
|
||||
width: double.maxFinite,
|
||||
child: setTextField(
|
||||
hintlbl: UiUtils.getTranslatedLabel(context, 'addYourBioHintLbl'),
|
||||
controller: authorBioC,
|
||||
focusNode: authorBioFocus,
|
||||
nextFocus: telegramLinkFocus,
|
||||
textInputAction: TextInputAction.newline,
|
||||
maxLines: 2));
|
||||
}
|
||||
|
||||
Widget setSocialMediaLink({required TextEditingController? linkController, required FocusNode currFocus, required FocusNode? nextFocus, required String typeForHintText}) {
|
||||
return setTextField(
|
||||
hintlbl: getAddLinkHint(context, typeForHintText),
|
||||
controller: linkController,
|
||||
focusNode: currFocus,
|
||||
nextFocus: nextFocus,
|
||||
textInputAction: TextInputAction.next,
|
||||
keyboardType: TextInputType.url);
|
||||
}
|
||||
|
||||
String getAddLinkHint(BuildContext context, String type) {
|
||||
final template = UiUtils.getTranslatedLabel(context, 'addLinkHereHintLbl');
|
||||
return template.replaceAll("{type}", type);
|
||||
}
|
||||
|
||||
Widget setMobileNumber() {
|
||||
return SizedBox(
|
||||
height: 60,
|
||||
child: setTextField(
|
||||
validatorMethod: (value) => value!.trim().isEmpty ? null : Validators.mobValidation(value, context),
|
||||
keyboardType: TextInputType.phone,
|
||||
hintlbl: UiUtils.getTranslatedLabel(context, 'mobileLbl'),
|
||||
textInputAction: TextInputAction.next,
|
||||
controller: monoC,
|
||||
focusNode: mobNoFocus,
|
||||
nextFocus: isThisUserAnAuthor ? authorBioFocus : emailFocus,
|
||||
isenable: (context.read<AuthCubit>().getType() != loginMbl) ? true : false));
|
||||
}
|
||||
|
||||
//set image camera
|
||||
getFromCamera() async {
|
||||
try {
|
||||
XFile? pickedFile = await ImagePicker().pickImage(source: ImageSource.camera);
|
||||
if (pickedFile != null) {
|
||||
Navigator.of(context).pop(); //pop dialog
|
||||
setState(() {
|
||||
image = File(pickedFile.path);
|
||||
profile = image!.path;
|
||||
});
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// set image gallery
|
||||
_getFromGallery() async {
|
||||
XFile? pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery, maxWidth: 1800, maxHeight: 1800);
|
||||
if (pickedFile != null) {
|
||||
setState(() {
|
||||
image = File(pickedFile.path);
|
||||
profile = image!.path;
|
||||
Navigator.of(context).pop(); //pop dialog
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
profileWidget() {
|
||||
return Container(padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 15), child: Center(child: profileImgWidget()));
|
||||
}
|
||||
|
||||
Widget profilePictureWidget() {
|
||||
final fallbackIcon = Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(shape: BoxShape.circle, border: BoxBorder.all(color: UiUtils.getColorScheme(context).primaryContainer)),
|
||||
child: Icon(Icons.person, color: UiUtils.getColorScheme(context).primaryContainer));
|
||||
|
||||
if (image != null) {
|
||||
return Image.file(image!, fit: BoxFit.fill, width: 75, height: 75);
|
||||
}
|
||||
|
||||
if (profile == null || profile!.trim().isEmpty) {
|
||||
return fallbackIcon;
|
||||
}
|
||||
|
||||
return Image.network(profile!,
|
||||
fit: BoxFit.fill, width: 85, errorBuilder: (_, __, ___) => fallbackIcon, loadingBuilder: (_, child, loadingProgress) => loadingProgress == null ? child : fallbackIcon);
|
||||
}
|
||||
|
||||
profileImgWidget() {
|
||||
return GestureDetector(
|
||||
onTap: () => UiUtils().showUploadImageBottomsheet(context: context, onCamera: getFromCamera, onGallery: _getFromGallery),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
CircleAvatar(
|
||||
radius: 46,
|
||||
backgroundColor: Colors.transparent,
|
||||
child: CircleAvatar(radius: 44, backgroundColor: Colors.transparent, child: ClipOval(clipBehavior: Clip.antiAliasWithSaveLayer, child: profilePictureWidget()))),
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(5),
|
||||
decoration:
|
||||
BoxDecoration(color: UiUtils.getColorScheme(context).primaryContainer, shape: BoxShape.circle, border: Border.all(width: 2, color: UiUtils.getColorScheme(context).secondary)),
|
||||
child: Icon(Icons.camera_alt_outlined, color: Theme.of(context).colorScheme.secondary, size: 20)))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
submitBtn(BuildContext context) {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(backgroundColor: Theme.of(context).primaryColor, shadowColor: Colors.transparent, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0))),
|
||||
child: Container(
|
||||
height: 45.0,
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
alignment: Alignment.center,
|
||||
child: (isSaving)
|
||||
? UiUtils.showCircularProgress(true, UiUtils.getColorScheme(context).primaryContainer)
|
||||
: CustomTextLabel(text: 'saveLbl', textStyle: Theme.of(this.context).textTheme.titleMedium?.copyWith(color: secondaryColor, fontWeight: FontWeight.w500, letterSpacing: 0.6)),
|
||||
),
|
||||
onPressed: () async {
|
||||
validateData();
|
||||
}));
|
||||
}
|
||||
|
||||
validateData() async {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
profileupdateprocess();
|
||||
} else {}
|
||||
}
|
||||
|
||||
profileupdateprocess() async {
|
||||
isSaving = true;
|
||||
//in case of Clearing Existing mobile number -> set mobile to blank, so it can be passed to replace existing value of mobile number as NULL mobile number won't be passed to APi
|
||||
mobile = monoC!.text.trim();
|
||||
|
||||
if (mobile == null && context.read<AuthCubit>().getType() != loginMbl && context.read<AuthCubit>().getMobile().isNotEmpty) {
|
||||
mobile = " ";
|
||||
}
|
||||
try {
|
||||
context.read<UpdateUserCubit>().setUpdateUser(
|
||||
context: context,
|
||||
name: nameC!.text,
|
||||
email: emailC!.text,
|
||||
mobile: mobile,
|
||||
filePath: (image != null) ? image!.path : "",
|
||||
authorBio: authorBioC?.text,
|
||||
whatsappLink: whatsappLinkC?.text,
|
||||
facebookLink: facebookLinkC?.text,
|
||||
telegramLink: telegramLinkC?.text,
|
||||
linkedInLink: linkedInLinkC?.text);
|
||||
} catch (e) {
|
||||
showSnackBar(e.toString(), context);
|
||||
}
|
||||
}
|
||||
|
||||
setTextField(
|
||||
{String? Function(String?)? validatorMethod,
|
||||
FocusNode? focusNode,
|
||||
FocusNode? nextFocus,
|
||||
TextInputAction? textInputAction,
|
||||
TextInputType? keyboardType,
|
||||
TextEditingController? controller,
|
||||
String? hintlbl,
|
||||
bool isenable = true,
|
||||
int? maxLines}) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: TextFormField(
|
||||
enabled: isenable,
|
||||
decoration: InputDecoration(
|
||||
hintText: hintlbl,
|
||||
hintStyle: Theme.of(context).textTheme.titleMedium?.copyWith(color: UiUtils.getColorScheme(context).outline.withOpacity(0.2)),
|
||||
filled: true,
|
||||
fillColor: Theme.of(context).colorScheme.surface,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 17, vertical: 17),
|
||||
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: UiUtils.getColorScheme(context).outline.withOpacity(0.7)), borderRadius: BorderRadius.circular(5.0)),
|
||||
enabledBorder: OutlineInputBorder(borderSide: BorderSide.none, borderRadius: BorderRadius.circular(5.0)),
|
||||
disabledBorder: OutlineInputBorder(borderSide: BorderSide.none, borderRadius: BorderRadius.circular(5.0)),
|
||||
),
|
||||
validator: validatorMethod,
|
||||
inputFormatters: [(focusNode == mobNoFocus) ? FilteringTextInputFormatter.digitsOnly : FilteringTextInputFormatter.singleLineFormatter],
|
||||
focusNode: focusNode,
|
||||
textInputAction: textInputAction,
|
||||
onEditingComplete: () {
|
||||
crntFocus = FocusNode();
|
||||
(nextFocus != null) ? fieldFocusChange(context, focusNode!, nextFocus) : focusNode?.unfocus();
|
||||
},
|
||||
onChanged: (String value) {
|
||||
setState(() => crntFocus = focusNode!);
|
||||
},
|
||||
onTapOutside: (val) => FocusScope.of(context).unfocus(),
|
||||
maxLines: (maxLines ?? 1),
|
||||
textAlignVertical: TextAlignVertical.center,
|
||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(color: (isenable) ? UiUtils.getColorScheme(context).primaryContainer : borderColor),
|
||||
keyboardType: keyboardType,
|
||||
controller: controller));
|
||||
}
|
||||
|
||||
fieldFocusChange(BuildContext context, FocusNode currentFocus, FocusNode nextFocus) {
|
||||
currentFocus.unfocus();
|
||||
FocusScope.of(context).requestFocus(nextFocus);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user