Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bbf5668

Browse files
authored
Merge pull request #59 from headlines-toolkit/fix_sync_models
Fix sync models
2 parents 0b2b6bf + ebee66b commit bbf5668

File tree

97 files changed

+3132
-3264
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+3132
-3264
lines changed

‎lib/account/bloc/account_bloc.dart‎

Lines changed: 119 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:ht_auth_repository/ht_auth_repository.dart';
66
import 'package:ht_data_repository/ht_data_repository.dart';
77
import 'package:ht_main/app/config/config.dart' as local_config;
88
import 'package:ht_shared/ht_shared.dart';
9+
import 'package:logging/logging.dart';
910

1011
part 'account_event.dart';
1112
part '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
}

‎lib/account/bloc/account_event.dart‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ class AccountSaveHeadlineToggled extends AccountEvent {
3333
List<Object> get props => [headline];
3434
}
3535

36-
class AccountFollowCategoryToggled extends AccountEvent {
37-
const AccountFollowCategoryToggled({required this.category});
38-
final Category category;
36+
class AccountFollowTopicToggled extends AccountEvent {
37+
const AccountFollowTopicToggled({required this.topic});
38+
final Topic topic;
3939

4040
@override
41-
List<Object> get props => [category];
41+
List<Object> get props => [topic];
4242
}
4343

4444
class AccountFollowSourceToggled extends AccountEvent {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /