Skip to content

Commit e23e19c

Browse files
authored
Merge pull request #27 from headlines-toolkit/refatcor_sync_teh_dashboard_logic_and_ui_with_updated_models
Refatcor sync teh dashboard logic and UI with updated models
2 parents 31d548a + 6e97d36 commit e23e19c

File tree

59 files changed

+2465
-2311
lines changed

Some content is hidden

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

59 files changed

+2465
-2311
lines changed

lib/app/bloc/app_bloc.dart

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:ht_auth_repository/ht_auth_repository.dart';
88
import 'package:ht_dashboard/app/config/config.dart' as local_config;
99
import 'package:ht_data_repository/ht_data_repository.dart';
1010
import 'package:ht_shared/ht_shared.dart';
11+
import 'package:logging/logging.dart';
1112

1213
part 'app_event.dart';
1314
part 'app_state.dart';
@@ -16,11 +17,13 @@ class AppBloc extends Bloc<AppEvent, AppState> {
1617
AppBloc({
1718
required HtAuthRepository authenticationRepository,
1819
required HtDataRepository<UserAppSettings> userAppSettingsRepository,
19-
required HtDataRepository<AppConfig> appConfigRepository,
20+
required HtDataRepository<RemoteConfig> appConfigRepository,
2021
required local_config.AppEnvironment environment,
22+
Logger? logger,
2123
}) : _authenticationRepository = authenticationRepository,
2224
_userAppSettingsRepository = userAppSettingsRepository,
2325
_appConfigRepository = appConfigRepository,
26+
_logger = logger ?? Logger('AppBloc'),
2427
super(
2528
AppState(environment: environment),
2629
) {
@@ -35,7 +38,8 @@ class AppBloc extends Bloc<AppEvent, AppState> {
3538

3639
final HtAuthRepository _authenticationRepository;
3740
final HtDataRepository<UserAppSettings> _userAppSettingsRepository;
38-
final HtDataRepository<AppConfig> _appConfigRepository;
41+
final HtDataRepository<RemoteConfig> _appConfigRepository;
42+
final Logger _logger;
3943
late final StreamSubscription<User?> _userSubscription;
4044

4145
/// Handles user changes and loads initial settings once user is available.
@@ -46,10 +50,15 @@ class AppBloc extends Bloc<AppEvent, AppState> {
4650
final user = event.user;
4751
final AppStatus status;
4852

49-
if (user != null &&
50-
(user.roles.contains(UserRoles.admin) ||
51-
user.roles.contains(UserRoles.publisher))) {
52-
status = AppStatus.authenticated;
53+
if (user != null) {
54+
if (user.dashboardRole == DashboardUserRole.admin ||
55+
user.dashboardRole == DashboardUserRole.publisher) {
56+
status = AppStatus.authenticated;
57+
} else if (user.appRole == AppUserRole.guestUser) {
58+
status = AppStatus.anonymous;
59+
} else {
60+
status = AppStatus.unauthenticated;
61+
}
5362
} else {
5463
status = AppStatus.unauthenticated;
5564
}
@@ -66,20 +75,47 @@ class AppBloc extends Bloc<AppEvent, AppState> {
6675
emit(state.copyWith(userAppSettings: userAppSettings));
6776
} on NotFoundException {
6877
// If settings not found, create default ones
69-
final defaultSettings = UserAppSettings(id: user.id);
78+
_logger.info(
79+
'User app settings not found for user ${user.id}. Creating default.',
80+
);
81+
final defaultSettings = UserAppSettings(
82+
id: user.id, // Use actual user ID for default settings
83+
displaySettings: const DisplaySettings(
84+
baseTheme: AppBaseTheme.system,
85+
accentTheme: AppAccentTheme.defaultBlue,
86+
fontFamily: 'SystemDefault',
87+
textScaleFactor: AppTextScaleFactor.medium,
88+
fontWeight: AppFontWeight.regular,
89+
),
90+
language: 'en',
91+
feedPreferences: const FeedDisplayPreferences(
92+
headlineDensity: HeadlineDensity.standard,
93+
headlineImageStyle: HeadlineImageStyle.largeThumbnail,
94+
showSourceInHeadlineFeed: true,
95+
showPublishDateInHeadlineFeed: true,
96+
),
97+
);
7098
await _userAppSettingsRepository.create(item: defaultSettings);
7199
emit(state.copyWith(userAppSettings: defaultSettings));
72-
} on HtHttpException catch (e) {
100+
} on HtHttpException catch (e, s) {
73101
// Handle HTTP exceptions during settings load
74-
print('Error loading user app settings: ${e.message}');
102+
_logger.severe(
103+
'Error loading user app settings for user ${user.id}: ${e.message}',
104+
e,
105+
s,
106+
);
75107
emit(state.copyWith(clearUserAppSettings: true));
76-
} catch (e) {
108+
} catch (e, s) {
77109
// Handle any other unexpected errors
78-
print('Unexpected error loading user app settings: $e');
110+
_logger.severe(
111+
'Unexpected error loading user app settings for user ${user.id}: $e',
112+
e,
113+
s,
114+
);
79115
emit(state.copyWith(clearUserAppSettings: true));
80116
}
81117
} else {
82-
// If user is unauthenticated, clear app settings
118+
// If user is unauthenticated or anonymous, clear app settings
83119
emit(state.copyWith(clearUserAppSettings: true));
84120
}
85121
}

lib/app/bloc/app_state.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ enum AppStatus {
1515
anonymous,
1616
}
1717

18+
/// {@template app_state}
19+
/// Represents the overall state of the application, including authentication
20+
/// status, current user, environment, and user-specific settings.
21+
/// {@endtemplate}
1822
class AppState extends Equatable {
1923
/// {@macro app_state}
2024
const AppState({

lib/app/view/app.dart

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,43 @@ import 'package:ht_dashboard/router/router.dart';
1818
import 'package:ht_dashboard/shared/theme/app_theme.dart';
1919
import 'package:ht_data_repository/ht_data_repository.dart';
2020
import 'package:ht_kv_storage_service/ht_kv_storage_service.dart';
21-
import 'package:ht_shared/ht_shared.dart';
21+
import 'package:ht_shared/ht_shared.dart' hide AppStatus;
22+
import 'package:logging/logging.dart';
2223

2324
class App extends StatelessWidget {
2425
const App({
2526
required HtAuthRepository htAuthenticationRepository,
2627
required HtDataRepository<Headline> htHeadlinesRepository,
27-
required HtDataRepository<Category> htCategoriesRepository,
28+
required HtDataRepository<Topic> htTopicsRepository,
2829
required HtDataRepository<Country> htCountriesRepository,
2930
required HtDataRepository<Source> htSourcesRepository,
3031
required HtDataRepository<UserAppSettings> htUserAppSettingsRepository,
31-
required HtDataRepository<UserContentPreferences>
32-
htUserContentPreferencesRepository,
33-
required HtDataRepository<AppConfig> htAppConfigRepository,
32+
required HtDataRepository<UserContentPreferences> htUserContentPreferencesRepository,
33+
required HtDataRepository<RemoteConfig> htRemoteConfigRepository,
3434
required HtDataRepository<DashboardSummary> htDashboardSummaryRepository,
3535
required HtKVStorageService kvStorageService,
3636
required AppEnvironment environment,
3737
super.key,
3838
}) : _htAuthenticationRepository = htAuthenticationRepository,
3939
_htHeadlinesRepository = htHeadlinesRepository,
40-
_htCategoriesRepository = htCategoriesRepository,
40+
_htTopicsRepository = htTopicsRepository,
4141
_htCountriesRepository = htCountriesRepository,
4242
_htSourcesRepository = htSourcesRepository,
4343
_htUserAppSettingsRepository = htUserAppSettingsRepository,
4444
_htUserContentPreferencesRepository = htUserContentPreferencesRepository,
45-
_htAppConfigRepository = htAppConfigRepository,
45+
_htRemoteConfigRepository = htRemoteConfigRepository,
4646
_kvStorageService = kvStorageService,
4747
_htDashboardSummaryRepository = htDashboardSummaryRepository,
4848
_environment = environment;
4949

5050
final HtAuthRepository _htAuthenticationRepository;
5151
final HtDataRepository<Headline> _htHeadlinesRepository;
52-
final HtDataRepository<Category> _htCategoriesRepository;
52+
final HtDataRepository<Topic> _htTopicsRepository;
5353
final HtDataRepository<Country> _htCountriesRepository;
5454
final HtDataRepository<Source> _htSourcesRepository;
5555
final HtDataRepository<UserAppSettings> _htUserAppSettingsRepository;
56-
final HtDataRepository<UserContentPreferences>
57-
_htUserContentPreferencesRepository;
58-
final HtDataRepository<AppConfig> _htAppConfigRepository;
56+
final HtDataRepository<UserContentPreferences> _htUserContentPreferencesRepository;
57+
final HtDataRepository<RemoteConfig> _htRemoteConfigRepository;
5958
final HtDataRepository<DashboardSummary> _htDashboardSummaryRepository;
6059
final HtKVStorageService _kvStorageService;
6160
final AppEnvironment _environment;
@@ -66,12 +65,12 @@ class App extends StatelessWidget {
6665
providers: [
6766
RepositoryProvider.value(value: _htAuthenticationRepository),
6867
RepositoryProvider.value(value: _htHeadlinesRepository),
69-
RepositoryProvider.value(value: _htCategoriesRepository),
68+
RepositoryProvider.value(value: _htTopicsRepository),
7069
RepositoryProvider.value(value: _htCountriesRepository),
7170
RepositoryProvider.value(value: _htSourcesRepository),
7271
RepositoryProvider.value(value: _htUserAppSettingsRepository),
7372
RepositoryProvider.value(value: _htUserContentPreferencesRepository),
74-
RepositoryProvider.value(value: _htAppConfigRepository),
73+
RepositoryProvider.value(value: _htRemoteConfigRepository),
7574
RepositoryProvider.value(value: _htDashboardSummaryRepository),
7675
RepositoryProvider.value(value: _kvStorageService),
7776
],
@@ -80,10 +79,12 @@ class App extends StatelessWidget {
8079
BlocProvider(
8180
create: (context) => AppBloc(
8281
authenticationRepository: context.read<HtAuthRepository>(),
83-
userAppSettingsRepository: context
84-
.read<HtDataRepository<UserAppSettings>>(),
85-
appConfigRepository: context.read<HtDataRepository<AppConfig>>(),
82+
userAppSettingsRepository:
83+
context.read<HtDataRepository<UserAppSettings>>(),
84+
appConfigRepository:
85+
context.read<HtDataRepository<RemoteConfig>>(),
8686
environment: _environment,
87+
logger: Logger('AppBloc'),
8788
),
8889
),
8990
BlocProvider(
@@ -93,21 +94,23 @@ class App extends StatelessWidget {
9394
),
9495
BlocProvider(
9596
create: (context) => AppConfigurationBloc(
96-
appConfigRepository: context.read<HtDataRepository<AppConfig>>(),
97+
remoteConfigRepository:
98+
context.read<HtDataRepository<RemoteConfig>>(),
9799
),
98100
),
99101
BlocProvider(
100102
create: (context) => ContentManagementBloc(
101103
headlinesRepository: context.read<HtDataRepository<Headline>>(),
102-
categoriesRepository: context.read<HtDataRepository<Category>>(),
104+
topicsRepository: context.read<HtDataRepository<Topic>>(),
103105
sourcesRepository: context.read<HtDataRepository<Source>>(),
104106
),
105107
),
106108
BlocProvider(
107109
create: (context) => DashboardBloc(
108-
dashboardSummaryRepository: context
109-
.read<HtDataRepository<DashboardSummary>>(),
110-
appConfigRepository: context.read<HtDataRepository<AppConfig>>(),
110+
dashboardSummaryRepository:
111+
context.read<HtDataRepository<DashboardSummary>>(),
112+
appConfigRepository:
113+
context.read<HtDataRepository<RemoteConfig>>(),
111114
headlinesRepository: context.read<HtDataRepository<Headline>>(),
112115
),
113116
),
@@ -122,6 +125,7 @@ class App extends StatelessWidget {
122125
}
123126

124127
class _AppView extends StatefulWidget {
128+
/// {@macro app_view}
125129
const _AppView({
126130
required this.htAuthenticationRepository,
127131
required this.environment,
@@ -215,7 +219,7 @@ class _AppViewState extends State<_AppView> {
215219
themeMode: switch (baseTheme) {
216220
AppBaseTheme.light => ThemeMode.light,
217221
AppBaseTheme.dark => ThemeMode.dark,
218-
AppBaseTheme.system || null => ThemeMode.system,
222+
_ => ThemeMode.system,
219223
},
220224
locale: language != null ? Locale(language) : null,
221225
),

lib/app/view/app_shell.dart

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,6 @@ class AppShell extends StatelessWidget {
2222
/// navigators in a stateful way.
2323
final StatefulNavigationShell navigationShell;
2424

25-
void _goBranch(int index) {
26-
navigationShell.goBranch(
27-
index,
28-
initialLocation: index == navigationShell.currentIndex,
29-
);
30-
}
31-
3225
@override
3326
Widget build(BuildContext context) {
3427
final l10n = context.l10n;
@@ -70,7 +63,12 @@ class AppShell extends StatelessWidget {
7063
),
7164
body: AdaptiveScaffold(
7265
selectedIndex: navigationShell.currentIndex,
73-
onSelectedIndexChange: _goBranch,
66+
onSelectedIndexChange: (index) {
67+
navigationShell.goBranch(
68+
index,
69+
initialLocation: index == navigationShell.currentIndex,
70+
);
71+
},
7472
destinations: [
7573
NavigationDestination(
7674
icon: const Icon(Icons.dashboard_outlined),

lib/app_configuration/bloc/app_configuration_bloc.dart

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import 'package:bloc/bloc.dart';
22
import 'package:equatable/equatable.dart';
33
import 'package:ht_data_repository/ht_data_repository.dart';
4-
import 'package:ht_shared/ht_shared.dart'; // Use AppConfig from ht_shared
4+
import 'package:ht_shared/ht_shared.dart'; // Use RemoteConfig from ht_shared
55

66
part 'app_configuration_event.dart';
77
part 'app_configuration_state.dart';
88

99
class AppConfigurationBloc
1010
extends Bloc<AppConfigurationEvent, AppConfigurationState> {
1111
AppConfigurationBloc({
12-
required HtDataRepository<AppConfig> appConfigRepository,
13-
}) : _appConfigRepository = appConfigRepository,
12+
required HtDataRepository<RemoteConfig> remoteConfigRepository,
13+
}) : _remoteConfigRepository = remoteConfigRepository,
1414
super(
1515
const AppConfigurationState(),
1616
) {
@@ -20,20 +20,20 @@ class AppConfigurationBloc
2020
on<AppConfigurationDiscarded>(_onAppConfigurationDiscarded);
2121
}
2222

23-
final HtDataRepository<AppConfig> _appConfigRepository;
23+
final HtDataRepository<RemoteConfig> _remoteConfigRepository;
2424

2525
Future<void> _onAppConfigurationLoaded(
2626
AppConfigurationLoaded event,
2727
Emitter<AppConfigurationState> emit,
2828
) async {
2929
emit(state.copyWith(status: AppConfigurationStatus.loading));
3030
try {
31-
final appConfig = await _appConfigRepository.read(id: 'app_config');
31+
final remoteConfig = await _remoteConfigRepository.read(id: 'app_config');
3232
emit(
3333
state.copyWith(
3434
status: AppConfigurationStatus.success,
35-
appConfig: appConfig,
36-
originalAppConfig: appConfig, // Store the original config
35+
remoteConfig: remoteConfig,
36+
originalRemoteConfig: remoteConfig, // Store the original config
3737
isDirty: false,
3838
clearShowSaveSuccess:
3939
true, // Clear any previous success snackbar flag
@@ -62,15 +62,15 @@ class AppConfigurationBloc
6262
) async {
6363
emit(state.copyWith(status: AppConfigurationStatus.loading));
6464
try {
65-
final updatedConfig = await _appConfigRepository.update(
66-
id: event.appConfig.id,
67-
item: event.appConfig,
65+
final updatedConfig = await _remoteConfigRepository.update(
66+
id: event.remoteConfig.id,
67+
item: event.remoteConfig,
6868
);
6969
emit(
7070
state.copyWith(
7171
status: AppConfigurationStatus.success,
72-
appConfig: updatedConfig,
73-
originalAppConfig: updatedConfig, // Update original config on save
72+
remoteConfig: updatedConfig,
73+
originalRemoteConfig: updatedConfig, // Update original config on save
7474
isDirty: false,
7575
showSaveSuccess: true, // Set flag to show success snackbar
7676
),
@@ -98,7 +98,7 @@ class AppConfigurationBloc
9898
) {
9999
emit(
100100
state.copyWith(
101-
appConfig: event.appConfig,
101+
remoteConfig: event.remoteConfig,
102102
isDirty: true,
103103
clearErrorMessage: true, // Clear any previous error messages
104104
clearShowSaveSuccess: true, // Clear success snackbar on field change
@@ -112,7 +112,7 @@ class AppConfigurationBloc
112112
) {
113113
emit(
114114
state.copyWith(
115-
appConfig: state.originalAppConfig, // Revert to original config
115+
remoteConfig: state.originalRemoteConfig, // Revert to original config
116116
isDirty: false,
117117
clearErrorMessage: true, // Clear any previous error messages
118118
clearShowSaveSuccess: true, // Clear success snackbar

lib/app_configuration/bloc/app_configuration_event.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ class AppConfigurationLoaded extends AppConfigurationEvent {
2424
/// {@endtemplate}
2525
class AppConfigurationUpdated extends AppConfigurationEvent {
2626
/// {@macro app_configuration_updated}
27-
const AppConfigurationUpdated(this.appConfig);
27+
const AppConfigurationUpdated(this.remoteConfig);
2828

2929
/// The updated application configuration.
30-
final AppConfig appConfig;
30+
final RemoteConfig remoteConfig;
3131

3232
@override
33-
List<Object?> get props => [appConfig];
33+
List<Object?> get props => [remoteConfig];
3434
}
3535

3636
/// {@template app_configuration_discarded}
@@ -50,12 +50,12 @@ class AppConfigurationDiscarded extends AppConfigurationEvent {
5050
class AppConfigurationFieldChanged extends AppConfigurationEvent {
5151
/// {@macro app_configuration_field_changed}
5252
const AppConfigurationFieldChanged({
53-
this.appConfig,
53+
this.remoteConfig,
5454
});
5555

56-
/// The partially or fully updated AppConfig object.
57-
final AppConfig? appConfig;
56+
/// The partially or fully updated RemoteConfig object.
57+
final RemoteConfig? remoteConfig;
5858

5959
@override
60-
List<Object?> get props => [appConfig];
60+
List<Object?> get props => [remoteConfig];
6161
}

0 commit comments

Comments
 (0)