Skip to content

Commit

Permalink
Merge pull request #31 from ucmazmehmet/main
Browse files Browse the repository at this point in the history
Unittest and home screen refactoring
  • Loading branch information
cevheri authored Nov 21, 2024
2 parents 93a8a96 + 3f53208 commit 781946b
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 87 deletions.
5 changes: 5 additions & 0 deletions lib/configuration/app_key_constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import 'package:flutter/material.dart';

const Key drawerButtonLogout = Key("drawerButtonLogout");
const Key drawerButtonLogoutYes = Key("drawerButtonLogoutYes");
const Key drawerButtonLogoutNo = Key("drawerButtonLogoutNo");
1 change: 1 addition & 0 deletions lib/configuration/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ class LocaleConstants {
static const Map<String, String> languages = {'en': 'English'};
static const String langStorageKey = 'locale';
static const String logoLightUrl = 'assets/images/logoLight.png';
static const String defaultImgUrl = 'assets/images/img.png';
}
2 changes: 1 addition & 1 deletion lib/data/repository/account_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class AccountRepository {
final httpResponse = await HttpUtils.getRequest("/$_resource");
var response = HttpUtils.decodeUTF8(httpResponse.body.toString());
var result = User.fromJsonString(response)!;
debugPrint("END:getAccount successful - response : $response}");
debugPrint("END:getAccount successful - response : ${response.length}}");
return result;
}

Expand Down
168 changes: 95 additions & 73 deletions lib/main/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,87 +45,109 @@ import '../presentation/screen/user/list/list_user_screen.dart';
class App extends StatelessWidget {
final String language;
final AdaptiveThemeMode initialTheme;

const App({super.key, required this.language});
App({super.key, required this.language, required this.initialTheme});

@override
Widget build(BuildContext context) {
return buildHomeApp();
}

AdaptiveTheme buildHomeApp() {
return AdaptiveTheme(
light: ThemeData(
useMaterial3: false,
brightness: Brightness.light,
colorSchemeSeed: Colors.blueGrey,
),
dark: ThemeData(
useMaterial3: false,
brightness: Brightness.dark,
primarySwatch: Colors.blueGrey,
),
light: _buildLightTheme(),
dark: _buildDarkTheme(),
debugShowFloatingThemeButton: false,
initial: AdaptiveThemeMode.dark,
initial: initialTheme,
builder: (light, dark) {
return MultiBlocProvider(
providers: [
BlocProvider<AuthorityBloc>(create: (_) => AuthorityBloc(authorityRepository: AuthorityRepository())),
BlocProvider<AccountBloc>(create: (_) => AccountBloc(accountRepository: AccountRepository())),
BlocProvider<UserBloc>(create: (_) => UserBloc(userRepository: UserRepository())),
BlocProvider<CityBloc>(create: (_) => CityBloc(cityRepository: CityRepository())),
BlocProvider<DistrictBloc>(create: (_) => DistrictBloc(districtRepository: DistrictRepository())),
BlocProvider<DrawerBloc>(create: (_) => DrawerBloc(loginRepository: LoginRepository(), menuRepository: MenuRepository())),
],
child: GetMaterialApp(
theme: light,
darkTheme: dark,
debugShowCheckedModeBanner: ProfileConstants.isDevelopment,
debugShowMaterialGrid: false,
localizationsDelegates: const [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
locale: Locale(language),
initialRoute: initialRouteControl(),
routes: {
ApplicationRoutes.home: (context) {
return BlocProvider<AccountBloc>(
create: (context) => AccountBloc(accountRepository: AccountRepository())..add(const AccountLoad()), child: HomeScreen());
},
ApplicationRoutes.account: (context) {
return BlocProvider<AccountBloc>(
create: (context) => AccountBloc(accountRepository: AccountRepository())..add(const AccountLoad()), child: AccountsScreen());
},
ApplicationRoutes.login: (context) {
return BlocProvider<LoginBloc>(create: (context) => LoginBloc(loginRepository: LoginRepository()), child: LoginScreen());
},
ApplicationRoutes.settings: (context) {
return BlocProvider<SettingsBloc>(
create: (context) => SettingsBloc(accountRepository: AccountRepository()), child: const SettingsScreen());
},
ApplicationRoutes.forgotPassword: (context) {
return BlocProvider<ForgotPasswordBloc>(
create: (context) => ForgotPasswordBloc(accountRepository: AccountRepository()), child: ForgotPasswordScreen());
},
ApplicationRoutes.register: (context) {
return BlocProvider<RegisterBloc>(
create: (context) => RegisterBloc(accountRepository: AccountRepository()), child: RegisterScreen());
},
ApplicationRoutes.changePassword: (context) {
return BlocProvider<ChangePasswordBloc>(
create: (context) => ChangePasswordBloc(accountRepository: AccountRepository()), child: ChangePasswordScreen());
},
ApplicationRoutes.logout: (context) => const LogoutConfirmationDialog(),
ApplicationRoutes.createUser: (context) {
return BlocProvider<UserBloc>(create: (context) => UserBloc(userRepository: UserRepository()), child: CreateUserScreen());
},
ApplicationRoutes.listUsers: (context) {
return BlocProvider<UserBloc>(create: (context) => UserBloc(userRepository: UserRepository()), child: ListUserScreen());
},
},
),
);
return _buildMultiBlocProvider(light, dark);
},
);
}

ThemeData _buildDarkTheme() {
return ThemeData(
useMaterial3: false,
brightness: Brightness.dark,
primarySwatch: Colors.blueGrey,
);
}

ThemeData _buildLightTheme() {
return ThemeData(
useMaterial3: false,
brightness: Brightness.light,
colorSchemeSeed: Colors.blueGrey,
);
}

MultiBlocProvider _buildMultiBlocProvider(ThemeData light, ThemeData dark) {
return MultiBlocProvider(
providers: [
BlocProvider<AuthorityBloc>(create: (_) => AuthorityBloc(authorityRepository: AuthorityRepository())),
BlocProvider<AccountBloc>(create: (_) => AccountBloc(accountRepository: AccountRepository())),
BlocProvider<UserBloc>(create: (_) => UserBloc(userRepository: UserRepository())),
BlocProvider<CityBloc>(create: (_) => CityBloc(cityRepository: CityRepository())),
BlocProvider<DistrictBloc>(create: (_) => DistrictBloc(districtRepository: DistrictRepository())),
BlocProvider<DrawerBloc>(create: (_) => DrawerBloc(loginRepository: LoginRepository(), menuRepository: MenuRepository())),
],
child: _buildGetMaterialApp(light, dark),
);
}

GetMaterialApp _buildGetMaterialApp(ThemeData light, ThemeData dark) {
return GetMaterialApp(
theme: light,
darkTheme: dark,
debugShowCheckedModeBanner: ProfileConstants.isDevelopment,
debugShowMaterialGrid: false,
localizationsDelegates: const [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
locale: Locale(language),
initialRoute: initialRouteControl(),
routes: _initialRoutes,
);
}

final _initialRoutes = {
ApplicationRoutes.home: (context) {
return BlocProvider<AccountBloc>(
create: (context) => AccountBloc(accountRepository: AccountRepository())..add(const AccountLoad()), child: HomeScreen());
},
ApplicationRoutes.account: (context) {
return BlocProvider<AccountBloc>(
create: (context) => AccountBloc(accountRepository: AccountRepository())..add(const AccountLoad()), child: AccountsScreen());
},
ApplicationRoutes.login: (context) {
return BlocProvider<LoginBloc>(create: (context) => LoginBloc(loginRepository: LoginRepository()), child: LoginScreen());
},
ApplicationRoutes.settings: (context) {
return BlocProvider<SettingsBloc>(
create: (context) => SettingsBloc(accountRepository: AccountRepository()), child: const SettingsScreen());
},
ApplicationRoutes.forgotPassword: (context) {
return BlocProvider<ForgotPasswordBloc>(
create: (context) => ForgotPasswordBloc(accountRepository: AccountRepository()), child: ForgotPasswordScreen());
},
ApplicationRoutes.register: (context) {
return BlocProvider<RegisterBloc>(create: (context) => RegisterBloc(accountRepository: AccountRepository()), child: RegisterScreen());
},
ApplicationRoutes.changePassword: (context) {
return BlocProvider<ChangePasswordBloc>(
create: (context) => ChangePasswordBloc(accountRepository: AccountRepository()), child: ChangePasswordScreen());
},
ApplicationRoutes.logout: (context) => const LogoutConfirmationDialog(),
ApplicationRoutes.createUser: (context) {
return BlocProvider<UserBloc>(create: (context) => UserBloc(userRepository: UserRepository()), child: CreateUserScreen());
},
ApplicationRoutes.listUsers: (context) {
return BlocProvider<UserBloc>(create: (context) => UserBloc(userRepository: UserRepository()), child: ListUserScreen());
},
};
}
4 changes: 3 additions & 1 deletion lib/main/main_local.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc_advance/configuration/local_storage.dart';
Expand All @@ -16,10 +17,11 @@ void main() async {
initializeJsonMapper();
WidgetsFlutterBinding.ensureInitialized();
const defaultLanguage = "en";
const initialTheme = AdaptiveThemeMode.dark;
await AppLocalStorage().save(StorageKeys.language.name, defaultLanguage);

WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then((_) {
runApp(const App(language: defaultLanguage));
runApp(App(language: defaultLanguage, initialTheme: initialTheme));
});
}
4 changes: 3 additions & 1 deletion lib/main/main_prod.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc_advance/configuration/environment.dart';
Expand All @@ -17,10 +18,11 @@ void main() async {
WidgetsFlutterBinding.ensureInitialized();

const defaultLanguage = "en";
const initialTheme = AdaptiveThemeMode.dark;
await AppLocalStorage().save(StorageKeys.language.name, defaultLanguage);

WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then((_) {
runApp(const App(language: defaultLanguage));
runApp(App(language: defaultLanguage, initialTheme: initialTheme));
});
}
1 change: 1 addition & 0 deletions lib/presentation/common_blocs/account/account_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
try {
User user = await _accountRepository.getAccount();
await AppLocalStorage().save(StorageKeys.roles.name, user.authorities);
await AppLocalStorage().save(StorageKeys.username.name, user.login);

emit(state.copyWith(account: user, status: AccountStatus.success));
log("AccountBloc._onLoad end : ${state.account}, ${state.status}");
Expand Down
18 changes: 11 additions & 7 deletions lib/presentation/common_widgets/drawer/drawer_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:expansion_tile_card/expansion_tile_card.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_bloc_advance/configuration/app_key_constants.dart';
import 'package:flutter_bloc_advance/configuration/local_storage.dart';
import 'package:flutter_bloc_advance/utils/security_utils.dart';
import 'package:string_2_icon/string_2_icon.dart';
Expand Down Expand Up @@ -55,6 +56,7 @@ class ApplicationDrawer extends StatelessWidget {
child: SizedBox(
width: double.infinity,
child: ElevatedButton(
key: drawerButtonLogout,
style: ElevatedButton.styleFrom(elevation: 0),
onPressed: () => logOutDialog(context),
child: Text(S.of(context).logout, textAlign: TextAlign.center),
Expand Down Expand Up @@ -83,13 +85,13 @@ class ApplicationDrawer extends StatelessWidget {

ListTile _buildMenuListListTile(List<dynamic> parentMenus, int index, BuildContext context) {
return ListTile(
leading: Icon(String2Icon.getIconDataFromString(parentMenus[index].icon)),
title: Text(S.of(context).translate_menu_title(parentMenus[index].name), style: Theme.of(context).textTheme.bodyMedium),
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(context, parentMenus[index].url);
},
);
leading: Icon(String2Icon.getIconDataFromString(parentMenus[index].icon)),
title: Text(S.of(context).translate_menu_title(parentMenus[index].name), style: Theme.of(context).textTheme.bodyMedium),
onTap: () {
Navigator.pop(context);
Navigator.pushNamed(context, parentMenus[index].url);
},
);
}

ExpansionTileCard _buildMenuListUserManagement(DrawerState state, List<dynamic> parentMenus, int index, BuildContext context) {
Expand Down Expand Up @@ -168,10 +170,12 @@ class ApplicationDrawer extends StatelessWidget {
content: Text(S.of(context).logout_sure),
actions: [
TextButton(
key: drawerButtonLogoutYes,
onPressed: () => onLogout(context),
child: Text(S.of(context).yes),
),
TextButton(
key: drawerButtonLogoutNo,
onPressed: () => onCancel(context),
child: Text(S.of(context).no),
),
Expand Down
9 changes: 5 additions & 4 deletions lib/presentation/screen/home/home_screen.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_bloc_advance/configuration/constants.dart';
import 'package:flutter_bloc_advance/utils/app_constants.dart';

import '../../../configuration/routes.dart';
import '../../../data/repository/login_repository.dart';
import '../../../data/repository/menu_repository.dart';
import '../../../generated/l10n.dart';
import '../../common_blocs/account/account.dart';
import '../../common_widgets/drawer/drawer_bloc/drawer_bloc.dart';
import '../../common_widgets/drawer/drawer_widget.dart';
Expand All @@ -32,7 +33,7 @@ class HomeScreen extends StatelessWidget {
builder: (context, state) {
if (state.status == AccountStatus.success) {
return Scaffold(
appBar: AppBar(title: Text(S.of(context).description)),
appBar: AppBar(title: const Text(AppConstants.appName)),
key: _scaffoldKey,
body: Center(child: Column(children: [backgroundImage(context)])),
drawer: _buildDrawer(context),
Expand All @@ -54,7 +55,7 @@ class HomeScreen extends StatelessWidget {
height: 300,
width: 300,
decoration: const BoxDecoration(
image: DecorationImage(image: AssetImage("assets/images/logoLight.png"), scale: 1, fit: BoxFit.contain),
image: DecorationImage(image: AssetImage(LocaleConstants.logoLightUrl), scale: 1, fit: BoxFit.contain),
),
),
),
Expand All @@ -68,7 +69,7 @@ class HomeScreen extends StatelessWidget {
width: double.infinity,
decoration: BoxDecoration(
image: DecorationImage(
image: const AssetImage("assets/images/img.png"),
image: const AssetImage(LocaleConstants.defaultImgUrl),
colorFilter: ColorFilter.mode(
AdaptiveTheme.of(context).mode.isDark ? Colors.black.withOpacity(0.1) : Colors.white.withOpacity(0.1), BlendMode.dstIn),
),
Expand Down
Loading

0 comments on commit 781946b

Please sign in to comment.