Skip to content

Feature_custom_envirement_messages #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 20, 2025
30 changes: 15 additions & 15 deletions lib/app/bloc/app_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flex_color_scheme/flex_color_scheme.dart';
import 'package:flutter/material.dart';
import 'package:ht_auth_repository/ht_auth_repository.dart';
import 'package:ht_data_repository/ht_data_repository.dart';
import 'package:ht_main/app/config/config.dart' as local_config;
import 'package:ht_shared/ht_shared.dart'; // Import shared models and exceptions

part 'app_event.dart';
Expand All @@ -15,24 +16,23 @@ class AppBloc extends Bloc<AppEvent, AppState> {
AppBloc({
required HtAuthRepository authenticationRepository,
required HtDataRepository<UserAppSettings> userAppSettingsRepository,
required HtDataRepository<AppConfig> appConfigRepository, // Added
}) : _authenticationRepository = authenticationRepository,
_userAppSettingsRepository = userAppSettingsRepository,
_appConfigRepository = appConfigRepository, // Added
// Initialize with default state, load settings after user is known
// Provide a default UserAppSettings instance
super(
// AppConfig will be null initially, fetched later
const AppState(
settings: UserAppSettings(id: 'default'),
selectedBottomNavigationIndex: 0,
appConfig: null,
),
) {
required HtDataRepository<AppConfig> appConfigRepository,
required local_config.AppEnvironment environment, // Added
}) : _authenticationRepository = authenticationRepository,
_userAppSettingsRepository = userAppSettingsRepository,
_appConfigRepository = appConfigRepository,
super(
AppState(
settings: const UserAppSettings(id: 'default'),
selectedBottomNavigationIndex: 0,
appConfig: null,
environment: environment, // Pass environment to AppState
),
) {
on<AppUserChanged>(_onAppUserChanged);
on<AppSettingsRefreshed>(_onAppSettingsRefreshed);
on<AppConfigFetchRequested>(_onAppConfigFetchRequested);
on<AppUserAccountActionShown>(_onAppUserAccountActionShown); // Added
on<AppUserAccountActionShown>(_onAppUserAccountActionShown);
on<AppLogoutRequested>(_onLogoutRequested);
on<AppThemeModeChanged>(_onThemeModeChanged);
on<AppFlexSchemeChanged>(_onFlexSchemeChanged);
Expand Down
19 changes: 14 additions & 5 deletions lib/app/bloc/app_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class AppState extends Equatable {
this.status = AppStatus.initial,
this.user, // User is now nullable and defaults to null
this.locale, // Added locale
this.appConfig, // Added AppConfig
this.appConfig,
this.environment,
});

/// The index of the currently selected item in the bottom navigation bar.
Expand Down Expand Up @@ -66,7 +67,10 @@ class AppState extends Equatable {
final Locale? locale; // Added locale

/// The global application configuration (remote config).
final AppConfig? appConfig; // Added AppConfig
final AppConfig? appConfig;

/// The current application environment (e.g., production, development, demo).
final local_config.AppEnvironment? environment;

/// Creates a copy of the current state with updated values.
AppState copyWith({
Expand All @@ -79,10 +83,12 @@ class AppState extends Equatable {
User? user,
UserAppSettings? settings, // Add settings to copyWith
Locale? locale, // Added locale
AppConfig? appConfig, // Added AppConfig
AppConfig? appConfig,
local_config.AppEnvironment? environment, // Added AppEnvironment
bool clearFontFamily = false,
bool clearLocale = false, // Added to allow clearing locale
bool clearAppConfig = false, // Added to allow clearing appConfig
bool clearEnvironment = false, // Added to allow clearing environment
}) {
return AppState(
selectedBottomNavigationIndex:
Expand All @@ -95,7 +101,9 @@ class AppState extends Equatable {
user: user ?? this.user,
settings: settings ?? this.settings, // Copy settings
locale: clearLocale ? null : locale ?? this.locale, // Added locale
appConfig: clearAppConfig ? null : appConfig ?? this.appConfig, // Added
appConfig: clearAppConfig ? null : appConfig ?? this.appConfig,
environment:
clearEnvironment ? null : environment ?? this.environment, // Added
);
}

Expand All @@ -110,6 +118,7 @@ class AppState extends Equatable {
user,
settings, // Include settings in props
locale, // Added locale to props
appConfig, // Added AppConfig to props
appConfig,
environment,
];
}
14 changes: 11 additions & 3 deletions lib/app/view/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:ht_auth_repository/ht_auth_repository.dart'; // Auth Repository
import 'package:ht_data_repository/ht_data_repository.dart'; // Generic Data Repository
import 'package:ht_kv_storage_service/ht_kv_storage_service.dart'; // KV Storage Interface
import 'package:ht_main/app/bloc/app_bloc.dart';
import 'package:ht_main/app/config/app_environment.dart';
import 'package:ht_main/authentication/bloc/authentication_bloc.dart';
import 'package:ht_main/l10n/app_localizations.dart';
import 'package:ht_main/l10n/l10n.dart';
Expand All @@ -30,6 +31,7 @@ class App extends StatelessWidget {
htUserContentPreferencesRepository,
required HtDataRepository<AppConfig> htAppConfigRepository,
required HtKVStorageService kvStorageService,
required AppEnvironment environment, // Added
super.key,
}) : _htAuthenticationRepository = htAuthenticationRepository,
_htHeadlinesRepository = htHeadlinesRepository,
Expand All @@ -39,7 +41,8 @@ class App extends StatelessWidget {
_htUserAppSettingsRepository = htUserAppSettingsRepository,
_htUserContentPreferencesRepository = htUserContentPreferencesRepository,
_htAppConfigRepository = htAppConfigRepository,
_kvStorageService = kvStorageService;
_kvStorageService = kvStorageService,
_environment = environment; // Added

final HtAuthRepository _htAuthenticationRepository;
final HtDataRepository<Headline> _htHeadlinesRepository;
Expand All @@ -51,6 +54,7 @@ class App extends StatelessWidget {
_htUserContentPreferencesRepository;
final HtDataRepository<AppConfig> _htAppConfigRepository;
final HtKVStorageService _kvStorageService;
final AppEnvironment _environment; // Added

@override
Widget build(BuildContext context) {
Expand All @@ -76,8 +80,9 @@ class App extends StatelessWidget {
authenticationRepository: context.read<HtAuthRepository>(),
userAppSettingsRepository:
context.read<HtDataRepository<UserAppSettings>>(),
appConfigRepository: // Added
context.read<HtDataRepository<AppConfig>>(), // Added
appConfigRepository:
context.read<HtDataRepository<AppConfig>>(),
environment: _environment, // Pass environment
),
),
BlocProvider(
Expand All @@ -97,6 +102,7 @@ class App extends StatelessWidget {
htUserContentPreferencesRepository:
_htUserContentPreferencesRepository,
htAppConfigRepository: _htAppConfigRepository,
environment: _environment, // Pass environment
),
),
);
Expand All @@ -113,6 +119,7 @@ class _AppView extends StatefulWidget {
required this.htUserAppSettingsRepository,
required this.htUserContentPreferencesRepository,
required this.htAppConfigRepository,
required this.environment, // Added
});

final HtAuthRepository htAuthenticationRepository;
Expand All @@ -124,6 +131,7 @@ class _AppView extends StatefulWidget {
final HtDataRepository<UserContentPreferences>
htUserContentPreferencesRepository;
final HtDataRepository<AppConfig> htAppConfigRepository;
final AppEnvironment environment; // Added

@override
State<_AppView> createState() => _AppViewState();
Expand Down
26 changes: 26 additions & 0 deletions lib/authentication/view/email_code_verification_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:ht_main/app/bloc/app_bloc.dart'; // Added
import 'package:ht_main/app/config/config.dart'; // Added for AppEnvironment
import 'package:ht_main/authentication/bloc/authentication_bloc.dart';
import 'package:ht_main/l10n/l10n.dart';
import 'package:ht_main/shared/constants/app_spacing.dart';
Expand Down Expand Up @@ -72,6 +74,30 @@ class EmailCodeVerificationPage extends StatelessWidget {
), // Softer color
textAlign: TextAlign.center,
),
// Display demo code if in demo environment
BlocSelector<AppBloc, AppState, AppEnvironment?>(
selector: (state) => state.environment,
builder: (context, environment) {
if (environment == AppEnvironment.demo) {
return Column(
children: [
const SizedBox(height: AppSpacing.md),
Text(
l10n.demoVerificationCodeMessage(
'123456',
), // Demo code
style: textTheme.bodyMedium?.copyWith(
color: colorScheme.secondary,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
],
);
}
return const SizedBox.shrink();
},
),
const SizedBox(
height: AppSpacing.xl,
), // Increased spacing
Expand Down
6 changes: 5 additions & 1 deletion lib/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import 'package:ht_main/shared/localization/en_timeago_messages.dart';
import 'package:ht_shared/ht_shared.dart';
import 'package:timeago/timeago.dart' as timeago;

Future<Widget> bootstrap(app_config.AppConfig appConfig) async {
Future<Widget> bootstrap(
app_config.AppConfig appConfig,
app_config.AppEnvironment environment, // Added
) async {
WidgetsFlutterBinding.ensureInitialized();
Bloc.observer = const AppBlocObserver();

Expand Down Expand Up @@ -215,5 +218,6 @@ Future<Widget> bootstrap(app_config.AppConfig appConfig) async {
htUserContentPreferencesRepository: userContentPreferencesRepository,
htAppConfigRepository: appConfigRepository,
kvStorageService: kvStorage,
environment: environment, // Pass environment to App
);
}
6 changes: 6 additions & 0 deletions lib/l10n/app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,12 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Start following categories to see them here.'**
String get followedCategoriesEmptySubheadline;

/// Message shown in demo mode to provide the verification code
///
/// In en, this message translates to:
/// **'Demo Mode: Use code {code}'**
String demoVerificationCodeMessage(String code);
}

class _AppLocalizationsDelegate
Expand Down
5 changes: 5 additions & 0 deletions lib/l10n/app_localizations_ar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -705,4 +705,9 @@ class AppLocalizationsAr extends AppLocalizations {
@override
String get followedCategoriesEmptySubheadline =>
'Start following categories to see them here.';

@override
String demoVerificationCodeMessage(String code) {
return 'وضع العرض التوضيحي: استخدم الرمز $code';
}
}
5 changes: 5 additions & 0 deletions lib/l10n/app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -707,4 +707,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get followedCategoriesEmptySubheadline =>
'Start following categories to see them here.';

@override
String demoVerificationCodeMessage(String code) {
return 'Demo Mode: Use code $code';
}
}
10 changes: 10 additions & 0 deletions lib/l10n/arb/app_ar.arb
Original file line number Diff line number Diff line change
Expand Up @@ -895,5 +895,15 @@
"savedHeadlinesEmptySubheadline": "لم تقم بحفظ أي مقالات بعد. ابدأ الاستكشاف!",
"@savedHeadlinesEmptySubheadline": {
"description": "Subheadline for empty state on saved headlines page"
},
"demoVerificationCodeMessage": "وضع العرض التوضيحي: استخدم الرمز {code}",
"@demoVerificationCodeMessage": {
"description": "رسالة تظهر في وضع العرض التوضيحي لتوفير رمز التحقق",
"placeholders": {
"code": {
"type": "String",
"example": "123456"
}
}
}
}
10 changes: 10 additions & 0 deletions lib/l10n/arb/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -911,5 +911,15 @@
"followedCategoriesEmptySubheadline": "Start following categories to see them here.",
"@followedCategoriesEmptySubheadline": {
"description": "Subheadline for empty state on followed categories page"
},
"demoVerificationCodeMessage": "Demo Mode: Use code {code}",
"@demoVerificationCodeMessage": {
"description": "Message shown in demo mode to provide the verification code",
"placeholders": {
"code": {
"type": "String",
"example": "123456"
}
}
}
}
2 changes: 1 addition & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void main() async {
AppEnvironment.demo => AppConfig.demo(),
};

final appWidget = await bootstrap(appConfig);
final appWidget = await bootstrap(appConfig, currentEnvironment);

// Only remove the splash screen on web after the app is ready.
if (kIsWeb) {
Expand Down
Loading