@@ -6,6 +6,7 @@ import 'package:ht_auth_repository/ht_auth_repository.dart';
66import  'package:ht_data_repository/ht_data_repository.dart' ;
77import  'package:ht_main/app/config/config.dart'  as  local_config;
88import  'package:ht_shared/ht_shared.dart' ;
9+ import  'package:logging/logging.dart' ;
910
1011part  'account_event.dart' ;
1112part  'account_state.dart' ;
@@ -16,9 +17,11 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
1617 required  HtDataRepository <UserContentPreferences >
1718 userContentPreferencesRepository,
1819 required  local_config.AppEnvironment  environment,
20+  Logger ?  logger,
1921 }) :  _authenticationRepository =  authenticationRepository,
2022 _userContentPreferencesRepository =  userContentPreferencesRepository,
2123 _environment =  environment,
24+  _logger =  logger ??  Logger ('AccountBloc' ),
2225 super (const  AccountState ()) {
2326 // Listen to user changes from HtAuthRepository 
2427 _userSubscription =  _authenticationRepository.authStateChanges.listen ((
@@ -31,16 +34,16 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
3134 on < AccountUserChanged > (_onAccountUserChanged);
3235 on < AccountLoadUserPreferences > (_onAccountLoadUserPreferences);
3336 on < AccountSaveHeadlineToggled > (_onAccountSaveHeadlineToggled);
34-  on < AccountFollowCategoryToggled > (_onAccountFollowCategoryToggled );
37+  on < AccountFollowTopicToggled > (_onAccountFollowTopicToggled );
3538 on < AccountFollowSourceToggled > (_onAccountFollowSourceToggled);
36-  // AccountFollowCountryToggled handler removed 
3739 on < AccountClearUserPreferences > (_onAccountClearUserPreferences);
3840 }
3941
4042 final  HtAuthRepository  _authenticationRepository;
4143 final  HtDataRepository <UserContentPreferences >
4244 _userContentPreferencesRepository;
4345 final  local_config.AppEnvironment  _environment;
46+  final  Logger  _logger;
4447 late  StreamSubscription <User ?> _userSubscription;
4548
4649 Future <void > _onAccountUserChanged (
@@ -72,7 +75,7 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
7275 state.copyWith (
7376 status:  AccountStatus .success,
7477 preferences:  preferences,
75-  clearErrorMessage :  true ,
78+  clearError :  true ,
7679 ),
7780 );
7881 } on  NotFoundException  {
@@ -86,48 +89,54 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
8689 if  (_environment ==  local_config.AppEnvironment .demo) {
8790 // ignore: inference_failure_on_instance_creation 
8891 await  Future .delayed (const  Duration (milliseconds:  50 ));
89-  // After delay, re-attempt to read the preferences. 
90-  // This is crucial  because migration might have completed during the delay. 
92+  // After delay, re-attempt to read the preferences. This is crucial  
93+  // because migration might have completed during the delay. 
9194 try  {
9295 final  migratedPreferences =  await  _userContentPreferencesRepository
9396 .read (id:  event.userId, userId:  event.userId);
9497 emit (
9598 state.copyWith (
9699 status:  AccountStatus .success,
97100 preferences:  migratedPreferences,
98-  clearErrorMessage :  true ,
101+  clearError :  true ,
99102 ),
100103 );
101104 return ; // Exit if successfully read after migration 
102105 } on  NotFoundException  {
103106 // Still not found after delay, proceed to create default. 
104-  print (
107+  _logger. info (
105108 '[AccountBloc] UserContentPreferences still not found after ' 
106109 'migration delay. Creating default preferences.' ,
107110 );
108111 }
109112 }
110-  // If preferences not found (either initially or after re-attempt), 
111-  // create a default one for the user. 
112-  final  defaultPreferences =  UserContentPreferences (id:  event.userId);
113+  // If preferences not found (either initially or after re-attempt), create 
114+  // a default one for the user. 
115+  final  defaultPreferences =  UserContentPreferences (
116+  id:  event.userId,
117+  followedCountries:  const  [],
118+  followedSources:  const  [],
119+  followedTopics:  const  [],
120+  savedHeadlines:  const  [],
121+  );
113122 try  {
114123 await  _userContentPreferencesRepository.create (
115124 item:  defaultPreferences,
116125 userId:  event.userId,
117126 );
118127 emit (
119128 state.copyWith (
120-  status:  AccountStatus .success,
121129 preferences:  defaultPreferences,
122-  clearErrorMessage:  true ,
130+  clearError:  true ,
131+  status:  AccountStatus .success,
123132 ),
124133 );
125134 } on  ConflictException  {
126135 // If a conflict occurs during creation (e.g., another process 
127-  // created it concurrently), attempt to read it again to get the 
128-  // existing  one. This can happen if the migration service 
129-  // created it right after  the second NotFoundException. 
130-  print (
136+  // created it concurrently), attempt to read it again to get the existing  
137+  // one. This can happen if the migration service created it right after  
138+  // the second NotFoundException. 
139+  _logger. info (
131140 '[AccountBloc] Conflict during creation of UserContentPreferences. ' 
132141 'Attempting to re-read.' ,
133142 );
@@ -137,26 +146,44 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
137146 state.copyWith (
138147 status:  AccountStatus .success,
139148 preferences:  existingPreferences,
140-  clearErrorMessage :  true ,
149+  clearError :  true ,
141150 ),
142151 );
143-  } catch  (e) {
152+  } on  HtHttpException  catch  (e) {
153+  _logger.severe (
154+  'Failed to create default preferences with HtHttpException: $e ' ,
155+  );
156+  emit (state.copyWith (status:  AccountStatus .failure, error:  e));
157+  } catch  (e, st) {
158+  _logger.severe (
159+  'Failed to create default preferences with unexpected error: $e ' ,
160+  e,
161+  st,
162+  );
144163 emit (
145164 state.copyWith (
146165 status:  AccountStatus .failure,
147-  errorMessage:  'Failed to create default preferences: $e ' ,
166+  error:  OperationFailedException (
167+  'Failed to create default preferences: $e ' ,
168+  ),
148169 ),
149170 );
150171 }
151172 } on  HtHttpException  catch  (e) {
152-  emit (
153-  state.copyWith (status:  AccountStatus .failure, errorMessage:  e.message),
173+  _logger.severe (
174+  'AccountLoadUserPreferences failed with HtHttpException: $e ' ,
175+  );
176+  emit (state.copyWith (status:  AccountStatus .failure, error:  e));
177+  } catch  (e, st) {
178+  _logger.severe (
179+  'AccountLoadUserPreferences failed with unexpected error: $e ' ,
180+  e,
181+  st,
154182 );
155-  } catch  (e) {
156183 emit (
157184 state.copyWith (
158185 status:  AccountStatus .failure,
159-  errorMessage : 'An unexpected error occurred.'  ,
186+  error : OperationFailedException ( 'An unexpected error occurred: $ e '  ) ,
160187 ),
161188 );
162189 }
@@ -197,46 +224,51 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
197224 state.copyWith (
198225 status:  AccountStatus .success,
199226 preferences:  updatedPrefs,
200-  clearErrorMessage :  true ,
227+  clearError :  true ,
201228 ),
202229 );
203230 } on  HtHttpException  catch  (e) {
204-  emit (
205-  state.copyWith (status:  AccountStatus .failure, errorMessage:  e.message),
231+  _logger.severe (
232+  'AccountSaveHeadlineToggled failed with HtHttpException: $e ' ,
233+  );
234+  emit (state.copyWith (status:  AccountStatus .failure, error:  e));
235+  } catch  (e, st) {
236+  _logger.severe (
237+  'AccountSaveHeadlineToggled failed with unexpected error: $e ' ,
238+  e,
239+  st,
206240 );
207-  } catch  (e) {
208241 emit (
209242 state.copyWith (
210243 status:  AccountStatus .failure,
211-  errorMessage:  'Failed to update saved headlines.' ,
244+  error:  OperationFailedException (
245+  'Failed to update saved headlines: $e ' ,
246+  ),
212247 ),
213248 );
214249 }
215250 }
216251
217-  Future <void > _onAccountFollowCategoryToggled (
218-  AccountFollowCategoryToggled  event,
252+  Future <void > _onAccountFollowTopicToggled (
253+  AccountFollowTopicToggled  event,
219254 Emitter <AccountState > emit,
220255 ) async  {
221256 if  (state.user ==  null  ||  state.preferences ==  null ) return ;
222257 emit (state.copyWith (status:  AccountStatus .loading));
223258
224259 final  currentPrefs =  state.preferences! ;
225-  final  isCurrentlyFollowed =  currentPrefs.followedCategories .any (
226-  (c ) =>  c .id ==  event.category .id,
260+  final  isCurrentlyFollowed =  currentPrefs.followedTopics .any (
261+  (t ) =>  t .id ==  event.topic .id,
227262 );
228-  final  List <Category > updatedFollowedCategories ;
263+  final  List <Topic > updatedFollowedTopics ;
229264
230-  if  (isCurrentlyFollowed) {
231-  updatedFollowedCategories =  List .from (currentPrefs.followedCategories)
232-  ..removeWhere ((c) =>  c.id ==  event.category.id);
233-  } else  {
234-  updatedFollowedCategories =  List .from (currentPrefs.followedCategories)
235-  ..add (event.category);
236-  }
265+  updatedFollowedTopics =  isCurrentlyFollowed
266+  ?  (List .from (currentPrefs.followedTopics)
267+  ..removeWhere ((t) =>  t.id ==  event.topic.id))
268+  :  (List .from (currentPrefs.followedTopics)..add (event.topic));
237269
238270 final  updatedPrefs =  currentPrefs.copyWith (
239-  followedCategories :  updatedFollowedCategories ,
271+  followedTopics :  updatedFollowedTopics ,
240272 );
241273
242274 try  {
@@ -249,18 +281,26 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
249281 state.copyWith (
250282 status:  AccountStatus .success,
251283 preferences:  updatedPrefs,
252-  clearErrorMessage :  true ,
284+  clearError :  true ,
253285 ),
254286 );
255287 } on  HtHttpException  catch  (e) {
256-  emit (
257-  state.copyWith (status:  AccountStatus .failure, errorMessage:  e.message),
288+  _logger.severe (
289+  'AccountFollowTopicToggled failed with HtHttpException: $e ' ,
290+  );
291+  emit (state.copyWith (status:  AccountStatus .failure, error:  e));
292+  } catch  (e, st) {
293+  _logger.severe (
294+  'AccountFollowTopicToggled failed with unexpected error: $e ' ,
295+  e,
296+  st,
258297 );
259-  } catch  (e) {
260298 emit (
261299 state.copyWith (
262300 status:  AccountStatus .failure,
263-  errorMessage:  'Failed to update followed categories.' ,
301+  error:  OperationFailedException (
302+  'Failed to update followed topics: $e ' ,
303+  ),
264304 ),
265305 );
266306 }
@@ -301,33 +341,45 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
301341 state.copyWith (
302342 status:  AccountStatus .success,
303343 preferences:  updatedPrefs,
304-  clearErrorMessage :  true ,
344+  clearError :  true ,
305345 ),
306346 );
307347 } on  HtHttpException  catch  (e) {
308-  emit (
309-  state.copyWith (status:  AccountStatus .failure, errorMessage:  e.message),
348+  _logger.severe (
349+  'AccountFollowSourceToggled failed with HtHttpException: $e ' ,
350+  );
351+  emit (state.copyWith (status:  AccountStatus .failure, error:  e));
352+  } catch  (e, st) {
353+  _logger.severe (
354+  'AccountFollowSourceToggled failed with unexpected error: $e ' ,
355+  e,
356+  st,
310357 );
311-  } catch  (e) {
312358 emit (
313359 state.copyWith (
314360 status:  AccountStatus .failure,
315-  errorMessage:  'Failed to update followed sources.' ,
361+  error:  OperationFailedException (
362+  'Failed to update followed sources: $e ' ,
363+  ),
316364 ),
317365 );
318366 }
319367 }
320368
321-  // _onAccountFollowCountryToggled method removed 
322- 323369 Future <void > _onAccountClearUserPreferences (
324370 AccountClearUserPreferences  event,
325371 Emitter <AccountState > emit,
326372 ) async  {
327373 emit (state.copyWith (status:  AccountStatus .loading));
328374 try  {
329375 // Create a new default preferences object to "clear" existing ones 
330-  final  defaultPreferences =  UserContentPreferences (id:  event.userId);
376+  final  defaultPreferences =  UserContentPreferences (
377+  id:  event.userId,
378+  followedCountries:  const  [],
379+  followedSources:  const  [],
380+  followedTopics:  const  [],
381+  savedHeadlines:  const  [],
382+  );
331383 await  _userContentPreferencesRepository.update (
332384 id:  event.userId,
333385 item:  defaultPreferences,
@@ -337,18 +389,26 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
337389 state.copyWith (
338390 status:  AccountStatus .success,
339391 preferences:  defaultPreferences,
340-  clearErrorMessage :  true ,
392+  clearError :  true ,
341393 ),
342394 );
343395 } on  HtHttpException  catch  (e) {
344-  emit (
345-  state.copyWith (status:  AccountStatus .failure, errorMessage:  e.message),
396+  _logger.severe (
397+  'AccountClearUserPreferences failed with HtHttpException: $e ' ,
398+  );
399+  emit (state.copyWith (status:  AccountStatus .failure, error:  e));
400+  } catch  (e, st) {
401+  _logger.severe (
402+  'AccountClearUserPreferences failed with unexpected error: $e ' ,
403+  e,
404+  st,
346405 );
347-  } catch  (e) {
348406 emit (
349407 state.copyWith (
350408 status:  AccountStatus .failure,
351-  errorMessage:  'Failed to clear user preferences.' ,
409+  error:  OperationFailedException (
410+  'Failed to clear user preferences: $e ' ,
411+  ),
352412 ),
353413 );
354414 }
0 commit comments