@@ -5,7 +5,9 @@ import 'package:equatable/equatable.dart';
55import 'package:flutter/widgets.dart' ;
66import 'package:flutter_bloc/flutter_bloc.dart' ;
77import 'package:freezed_annotation/freezed_annotation.dart' ;
8+ import 'package:get/get.dart' ;
89
10+ import '../../../data/constants/strings.dart' ;
911import '../../../data/services/local/image_service.dart' ;
1012import '../../../data/services/local/storage_service.dart' ;
1113import '../../../domain/models/status.dart' ;
@@ -27,6 +29,7 @@ class UpdateProfileBloc extends Bloc<UpdateProfileEvent, UpdateProfileState> {
2729 on < UpdateFocusField > (_onUpdateFocusField);
2830 on < ToggleObscure > (_onToggleObscure);
2931 on < UpdatePassword > (_onUpdatePassword);
32+ on < UpdateUserDetails > (_onUpdateUserDetails);
3033 }
3134
3235 static List <String > institutes = < String > [
@@ -37,27 +40,43 @@ class UpdateProfileBloc extends Bloc<UpdateProfileEvent, UpdateProfileState> {
3740 'Indian Institute of Technology Bombay' ,
3841 ];
3942
43+ static User get user => StorageService .user! ;
44+
45+ static Map <String , TextEditingController ?> controllers =
46+ < String , TextEditingController ? > {
47+ 'name' : TextEditingController (),
48+ 'username' : TextEditingController (),
49+ 'codechef' : TextEditingController (),
50+ 'codeforces' : TextEditingController (),
51+ 'hackerrank' : TextEditingController (),
52+ 'spoj' : TextEditingController (),
53+ 'leetcode' : TextEditingController (),
54+ 'old_pass' : TextEditingController (),
55+ 'new_pass' : TextEditingController (),
56+ 're_enter' : TextEditingController (),
57+ };
58+
59+ void _initializeTextField () {
60+ controllers['name' ]? .text = _currentUser.fullname;
61+ controllers['username' ]? .text = _currentUser.username ?? '' ;
62+ controllers['codechef' ]? .text = _currentUser.handle? .codechef ?? '' ;
63+ controllers['codeforces' ]? .text = _currentUser.handle? .codeforces ?? '' ;
64+ controllers['hackerrank' ]? .text = _currentUser.handle? .hackerrank ?? '' ;
65+ controllers['spoj' ]? .text = _currentUser.handle? .spoj ?? '' ;
66+ controllers['leetcode' ]? .text = _currentUser.handle? .leetcode ?? '' ;
67+ }
68+
4069 void _onInitialize (Initialize event, Emitter <UpdateProfileState > emit) async {
4170 final _instituteList = await UserRepository .getInstituteList ();
4271 if (_instituteList.isNotEmpty) {
4372 institutes = _instituteList;
4473 }
4574
46- final _controllers = < String , TextEditingController ? > {
47- 'codechef' : TextEditingController (),
48- 'codeforces' : TextEditingController (),
49- 'hackerrank' : TextEditingController (),
50- 'spoj' : TextEditingController (),
51- 'leetcode' : TextEditingController (),
52- 'old_pass' : TextEditingController (),
53- 'new_pass' : TextEditingController (),
54- 're_enter' : TextEditingController (),
55- };
75+ _initializeTextField ();
5676
5777 emit (state.copyWith (
5878 status: const Status (),
5979 user: _currentUser,
60- controllers: _controllers,
6180 ));
6281 }
6382
@@ -75,14 +94,13 @@ class UpdateProfileBloc extends Bloc<UpdateProfileEvent, UpdateProfileState> {
7594
7695 void _onSwitchView (SwitchView event, Emitter <UpdateProfileState > emit) {
7796 final currentState = state.showChangePasswordView;
78- final _controllers = state.controllers ;
79- _controllers ['old_pass' ]? .text = '' ;
80- _controllers ['new_pass' ]? .text = '' ;
81- _controllers ['re_enter' ]? .text = '' ;
97+ _initializeTextField () ;
98+ controllers ['old_pass' ]? .text = '' ;
99+ controllers ['new_pass' ]? .text = '' ;
100+ controllers ['re_enter' ]? .text = '' ;
82101 emit (state.copyWith (
83102 showChangePasswordView: ! currentState,
84103 activePasswordTextField: - 1 ,
85- controllers: _controllers,
86104 ));
87105 }
88106
@@ -108,8 +126,8 @@ class UpdateProfileBloc extends Bloc<UpdateProfileEvent, UpdateProfileState> {
108126 UpdatePassword event, Emitter <UpdateProfileState > emit) async {
109127 emit (state.copyWith (isUpdating: true ));
110128 try {
111- await UserRepository .updatePassword (state. controllers['old_pass' ]! .text,
112- state. controllers['new_pass' ]! .text);
129+ await UserRepository .updatePassword (controllers['old_pass' ]! .text. trim () ,
130+ controllers['new_pass' ]! .text. trim () );
113131 add (const SwitchView ());
114132 showSnackBar (message: 'Password Changed' );
115133 } on Failure catch (err) {
@@ -118,6 +136,108 @@ class UpdateProfileBloc extends Bloc<UpdateProfileEvent, UpdateProfileState> {
118136 emit (state.copyWith (isUpdating: false ));
119137 }
120138
139+ void _onUpdateUserDetails (
140+ UpdateUserDetails event, Emitter <UpdateProfileState > emit) async {
141+ isChanged = false ;
142+ emit (state.copyWith (isUpdating: true ));
143+
144+ final _errors = < String , dynamic > {};
145+
146+ /// Name Field Validation
147+ isChanged | = controllers['name' ]! .text.trim () != state.user? .fullname;
148+ if (controllers['name' ]! .text.isEmpty) {
149+ _errors['name' ] = 'Required Field' ;
150+ }
151+
152+ /// Username Field Validation
153+ if (controllers['username' ]! .text.isEmpty) {
154+ _errors['username' ] = 'Required Field' ;
155+ } else if (controllers['username' ]? .text.trim () != _currentUser.username) {
156+ isChanged = true ;
157+ final res = await UserRepository .isUsernameAvailable (
158+ controllers['username' ]! .text.trim ());
159+
160+ if (! res) _errors['username' ] = 'Already Taken' ;
161+ }
162+
163+ /// Handles Validation
164+ final platforms = [
165+ 'codechef' ,
166+ 'codeforces' ,
167+ 'hackerrank' ,
168+ 'spoj' ,
169+ 'leetcode'
170+ ];
171+ for (final platform in platforms) {
172+ final _handle = controllers[platform]! .text.trim ();
173+
174+ if (_handle.isEmpty) continue ;
175+
176+ if (! compareHandles (platform, _handle)) {
177+ isChanged | = true ;
178+ final res = await UserRepository .verifyHandle (platform, _handle);
179+
180+ if (! res) _errors[platform] = 'Invalid Handle' ;
181+ }
182+ }
183+
184+ /// Returns if errors are not empty
185+ if (_errors.keys.isNotEmpty || ! isChanged) {
186+ emit (state.copyWith (isUpdating: false , errors: _errors));
187+ return ;
188+ }
189+
190+ final _updatedData = < String , dynamic > {};
191+ _updatedData['fullname' ] = controllers['name' ]? .text.trim ();
192+ _updatedData['username' ] = controllers['username' ]? .text.trim ();
193+ _updatedData['institute' ] = state.user! .institute;
194+ _updatedData['handle.codechef' ] = controllers['codechef' ]? .text.trim ();
195+ _updatedData['handle.codeforces' ] = controllers['codeforces' ]? .text.trim ();
196+ _updatedData['handle.hackerrank' ] = controllers['hackerrank' ]? .text.trim ();
197+ _updatedData['handle.spoj' ] = controllers['spoj' ]? .text.trim ();
198+ _updatedData['handle.leetcode' ] = controllers['leetcode' ]? .text.trim ();
199+
200+ final statusCode = await UserRepository .updateUserDetails (_updatedData);
201+
202+ if (state.image != null ) {
203+ await UserRepository .uploadProfilePicture (state.image! );
204+ }
205+
206+ if (statusCode == 202 ) {
207+ StorageService .user = await UserRepository .fetchUserDetails ();
208+ showSnackBar (message: 'Updated Sucessfully' );
209+ Get .back (result: true );
210+ return ;
211+ }
212+
213+ emit (state.copyWith (isUpdating: false ));
214+ showSnackBar (message: AppStrings .genericError);
215+ }
216+
217+ /// Compares the value from [TextEditingController] and [User]
218+ /// model of that handle. Returns true if they are same
219+ bool compareHandles (String platform, String value) {
220+ switch (platform) {
221+ case 'codechef' :
222+ return value == state.user? .handle? .codechef;
223+
224+ case 'codeforces' :
225+ return value == state.user? .handle? .codeforces;
226+
227+ case 'hackerrank' :
228+ return value == state.user? .handle? .hackerrank;
229+
230+ case 'spoj' :
231+ return value == state.user? .handle? .spoj;
232+
233+ case 'leetcode' :
234+ return value == state.user? .handle? .leetcode;
235+
236+ default :
237+ return false ;
238+ }
239+ }
240+
121241 Future <bool > onWillPop () async {
122242 if (state.showChangePasswordView) {
123243 add (const SwitchView ());
@@ -129,4 +249,5 @@ class UpdateProfileBloc extends Bloc<UpdateProfileEvent, UpdateProfileState> {
129249
130250 final User _currentUser = StorageService .user! ;
131251 User _updatedUser = StorageService .user! ;
252+ bool isChanged = false ;
132253}
0 commit comments