-
2android/app/src/main/AndroidManifest.xml
-
BINandroid/app/src/main/res/mipmap-hdpi/launcher_icon.png
-
BINandroid/app/src/main/res/mipmap-mdpi/launcher_icon.png
-
BINandroid/app/src/main/res/mipmap-xhdpi/launcher_icon.png
-
BINandroid/app/src/main/res/mipmap-xxhdpi/launcher_icon.png
-
BINandroid/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png
-
BINassets/images/png/ic_select_language.png
-
BINassets/images/png/logo.png
-
2assets/languages/en.json
-
2assets/languages/fa.json
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
-
BINios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
-
12lib/core/language/language_cubit.dart
-
34lib/core/select_language/cubit/select_language_cubit.dart
-
132lib/core/select_language/screen/select_language_screen.dart
-
26lib/core/utils/app_utils.dart
-
37lib/core/widgets/loading_list_widget.dart
-
265lib/features/aabout_us/about_us_screen.dart
-
9lib/features/main/widget/main_item_widget.dart
-
161lib/features/posts/screen/posts_screen.dart
-
22lib/features/single_post/screen/single_post_screen.dart
-
28lib/features/splash/cubit/splash_cubit.dart
-
83lib/features/splash/screen/splash_screen.dart
-
119lib/main.dart
-
12pubspec.lock
-
7pubspec.yaml
After Width: 72 | Height: 72 | Size: 1.8 KiB |
After Width: 48 | Height: 48 | Size: 1.1 KiB |
After Width: 96 | Height: 96 | Size: 2.6 KiB |
After Width: 144 | Height: 144 | Size: 4.2 KiB |
After Width: 192 | Height: 192 | Size: 5.9 KiB |
After Width: 73 | Height: 37 | Size: 996 B |
After Width: 1772 | Height: 1772 | Size: 58 KiB |
Before Width: 1024 | Height: 1024 | Size: 11 KiB After Width: 1024 | Height: 1024 | Size: 39 KiB |
Before Width: 20 | Height: 20 | Size: 295 B After Width: 20 | Height: 20 | Size: 404 B |
Before Width: 40 | Height: 40 | Size: 406 B After Width: 40 | Height: 40 | Size: 919 B |
Before Width: 60 | Height: 60 | Size: 450 B After Width: 60 | Height: 60 | Size: 1.4 KiB |
Before Width: 29 | Height: 29 | Size: 282 B After Width: 29 | Height: 29 | Size: 629 B |
Before Width: 58 | Height: 58 | Size: 462 B After Width: 58 | Height: 58 | Size: 1.4 KiB |
Before Width: 87 | Height: 87 | Size: 704 B After Width: 87 | Height: 87 | Size: 2.3 KiB |
Before Width: 40 | Height: 40 | Size: 406 B After Width: 40 | Height: 40 | Size: 919 B |
Before Width: 80 | Height: 80 | Size: 586 B After Width: 80 | Height: 80 | Size: 2.1 KiB |
Before Width: 120 | Height: 120 | Size: 862 B After Width: 120 | Height: 120 | Size: 3.2 KiB |
After Width: 50 | Height: 50 | Size: 1.2 KiB |
After Width: 100 | Height: 100 | Size: 2.7 KiB |
After Width: 57 | Height: 57 | Size: 1.3 KiB |
After Width: 114 | Height: 114 | Size: 3.2 KiB |
Before Width: 120 | Height: 120 | Size: 862 B After Width: 120 | Height: 120 | Size: 3.2 KiB |
Before Width: 180 | Height: 180 | Size: 1.6 KiB After Width: 180 | Height: 180 | Size: 5.5 KiB |
After Width: 72 | Height: 72 | Size: 1.8 KiB |
After Width: 144 | Height: 144 | Size: 4.2 KiB |
Before Width: 76 | Height: 76 | Size: 762 B After Width: 76 | Height: 76 | Size: 1.9 KiB |
Before Width: 152 | Height: 152 | Size: 1.2 KiB After Width: 152 | Height: 152 | Size: 4.3 KiB |
Before Width: 167 | Height: 167 | Size: 1.4 KiB After Width: 167 | Height: 167 | Size: 5.1 KiB |
@ -0,0 +1,34 @@ |
|||||
|
import 'package:flutter_bloc/flutter_bloc.dart'; |
||||
|
import 'package:sonnat/core/language/language_cubit.dart'; |
||||
|
import 'package:sonnat/core/language/languages.dart'; |
||||
|
import 'package:sonnat/core/language/translator.dart'; |
||||
|
import 'package:sonnat/core/utils/base_cubit_type.dart'; |
||||
|
|
||||
|
class SelectLanguageCubit extends Cubit<BaseCubitType<SelectLanguageState>> { |
||||
|
|
||||
|
SelectLanguageCubit() : super(BaseCubitType(eventName: SelectLanguageState.empty)); |
||||
|
|
||||
|
void empty() => emit(BaseCubitType(eventName: SelectLanguageState.empty)); |
||||
|
|
||||
|
Future<void> selectLanguage(String language) async { |
||||
|
switch (language) { |
||||
|
case 'fa': |
||||
|
await Translator.setNewLanguage(Languages.fa); |
||||
|
emit(BaseCubitType(eventName: SelectLanguageState.loaded, data: CurrentLanguage.fa)); |
||||
|
return; |
||||
|
case 'en': |
||||
|
await Translator.setNewLanguage(Languages.en); |
||||
|
emit(BaseCubitType(eventName: SelectLanguageState.loaded, data: CurrentLanguage.en)); |
||||
|
return; |
||||
|
case 'ar': |
||||
|
await Translator.setNewLanguage(Languages.ar); |
||||
|
emit(BaseCubitType(eventName: SelectLanguageState.loaded, data: CurrentLanguage.ar)); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
enum SelectLanguageState { |
||||
|
empty, |
||||
|
loaded, |
||||
|
} |
@ -0,0 +1,132 @@ |
|||||
|
import 'package:flutter/material.dart'; |
||||
|
import 'package:flutter_bloc/flutter_bloc.dart'; |
||||
|
import 'package:sonnat/core/extensions/context_extension.dart'; |
||||
|
import 'package:sonnat/core/extensions/string_extension.dart'; |
||||
|
import 'package:sonnat/core/language/language_cubit.dart'; |
||||
|
import 'package:sonnat/core/select_language/cubit/select_language_cubit.dart'; |
||||
|
import 'package:sonnat/core/utils/base_cubit_type.dart'; |
||||
|
import 'package:sonnat/features/main/main_screen.dart'; |
||||
|
|
||||
|
class SelectLanguageScreen extends StatefulWidget { |
||||
|
const SelectLanguageScreen({super.key}); |
||||
|
|
||||
|
@override |
||||
|
State<SelectLanguageScreen> createState() => _SelectLanguageScreenState(); |
||||
|
} |
||||
|
|
||||
|
class _SelectLanguageScreenState extends State<SelectLanguageScreen> { |
||||
|
late final SelectLanguageCubit _cubit; |
||||
|
|
||||
|
@override |
||||
|
void initState() { |
||||
|
_cubit = BlocProvider.of<SelectLanguageCubit>(context); |
||||
|
super.initState(); |
||||
|
} |
||||
|
|
||||
|
@override |
||||
|
Widget build(BuildContext context) { |
||||
|
return Scaffold( |
||||
|
backgroundColor: const Color(0xff26237A), |
||||
|
body: SafeArea( |
||||
|
child: BlocBuilder<SelectLanguageCubit, BaseCubitType<SelectLanguageState>>( |
||||
|
builder: (context, state) { |
||||
|
switch (state.eventName!) { |
||||
|
case SelectLanguageState.empty: |
||||
|
break; |
||||
|
case SelectLanguageState.loaded: |
||||
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { |
||||
|
BlocProvider.of<LanguageCubit>(context).changeLanguage(); |
||||
|
Navigator.push( |
||||
|
context, |
||||
|
MaterialPageRoute( |
||||
|
builder: (context) { |
||||
|
return const MainScreen(); |
||||
|
}, |
||||
|
), |
||||
|
); |
||||
|
}); |
||||
|
break; |
||||
|
} |
||||
|
return Column( |
||||
|
children: [ |
||||
|
Expanded( |
||||
|
child: Column( |
||||
|
mainAxisAlignment: MainAxisAlignment.center, |
||||
|
children: [ |
||||
|
Image.asset( |
||||
|
'ic_select_language'.pngPath, |
||||
|
width: 72, |
||||
|
height: 36, |
||||
|
), |
||||
|
const SizedBox(height: 15), |
||||
|
const Text( |
||||
|
'Select Your Language', |
||||
|
style: TextStyle( |
||||
|
color: Color(0xffDEDEDE), |
||||
|
fontSize: 16, |
||||
|
fontFamily: 'Cairo', |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
GestureDetector( |
||||
|
child: const SelectLanguageButtonWidget(title: 'English'), |
||||
|
onTap: () { |
||||
|
_cubit.selectLanguage('en'); |
||||
|
}, |
||||
|
), |
||||
|
GestureDetector( |
||||
|
child: const SelectLanguageButtonWidget(title: 'العربیه'), |
||||
|
onTap: () { |
||||
|
_cubit.selectLanguage('fa'); |
||||
|
}, |
||||
|
), |
||||
|
GestureDetector( |
||||
|
child: const SelectLanguageButtonWidget(title: 'فارسی'), |
||||
|
onTap: () { |
||||
|
_cubit.selectLanguage('fa'); |
||||
|
}, |
||||
|
), |
||||
|
GestureDetector( |
||||
|
child: const SelectLanguageButtonWidget(title: 'اردو'), |
||||
|
onTap: () { |
||||
|
_cubit.selectLanguage('fa'); |
||||
|
}, |
||||
|
), |
||||
|
const SizedBox(height: 30), |
||||
|
], |
||||
|
); |
||||
|
}, |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class SelectLanguageButtonWidget extends StatelessWidget { |
||||
|
final String title; |
||||
|
|
||||
|
const SelectLanguageButtonWidget({super.key, required this.title}); |
||||
|
|
||||
|
@override |
||||
|
Widget build(BuildContext context) { |
||||
|
return Container( |
||||
|
width: context.width, |
||||
|
decoration: BoxDecoration( |
||||
|
color: const Color(0xff3733A1), |
||||
|
borderRadius: BorderRadius.circular(22), |
||||
|
), |
||||
|
alignment: Alignment.center, |
||||
|
padding: const EdgeInsets.symmetric(vertical: 14), |
||||
|
margin: const EdgeInsets.symmetric(vertical: 7.5, horizontal: 40), |
||||
|
child: Text( |
||||
|
title, |
||||
|
style: const TextStyle( |
||||
|
color: Color(0xffffffff), |
||||
|
fontSize: 16, |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
} |
@ -1,35 +1,30 @@ |
|||||
import 'package:flutter/material.dart'; |
import 'package:flutter/material.dart'; |
||||
import 'package:sonnat/core/extensions/context_extension.dart'; |
import 'package:sonnat/core/extensions/context_extension.dart'; |
||||
import 'package:sonnat/core/utils/app_constants.dart'; |
import 'package:sonnat/core/utils/app_constants.dart'; |
||||
import 'package:sonnat/core/widgets/shimmer.dart'; |
|
||||
|
|
||||
class LoadingListWidget extends StatelessWidget { |
class LoadingListWidget extends StatelessWidget { |
||||
const LoadingListWidget({super.key}); |
const LoadingListWidget({super.key}); |
||||
|
|
||||
@override |
@override |
||||
Widget build(BuildContext context) { |
Widget build(BuildContext context) { |
||||
return Shimmer.fromColors( |
|
||||
baseColor: Colors.black12, |
|
||||
highlightColor: Colors.white, |
|
||||
child: ListView.builder( |
|
||||
padding: EdgeInsets.zero, |
|
||||
itemBuilder: (_, __) => Container( |
|
||||
height: 200, |
|
||||
decoration: BoxDecoration( |
|
||||
color: const Color(0xffffffff), |
|
||||
borderRadius: BorderRadius.circular(16), |
|
||||
), |
|
||||
margin: EdgeInsets.only( |
|
||||
left: context.width * 26 / AppConstants.instance.appWidth, |
|
||||
right: context.width * 26 / AppConstants.instance.appWidth, |
|
||||
bottom: context.height * 8 / AppConstants.instance.appHeight, |
|
||||
top: context.height * 8 / AppConstants.instance.appHeight, |
|
||||
), |
|
||||
|
return ListView.builder( |
||||
|
padding: EdgeInsets.zero, |
||||
|
itemBuilder: (_, __) => Container( |
||||
|
height: 340, |
||||
|
decoration: BoxDecoration( |
||||
|
color: Colors.grey, |
||||
|
borderRadius: BorderRadius.circular(16), |
||||
|
), |
||||
|
margin: EdgeInsets.only( |
||||
|
left: context.width * 26 / AppConstants.instance.appWidth, |
||||
|
right: context.width * 26 / AppConstants.instance.appWidth, |
||||
|
bottom: context.height * 8 / AppConstants.instance.appHeight, |
||||
|
top: context.height * 8 / AppConstants.instance.appHeight, |
||||
), |
), |
||||
physics: const NeverScrollableScrollPhysics(), |
|
||||
shrinkWrap: true, |
|
||||
itemCount: 10, |
|
||||
), |
), |
||||
|
physics: const NeverScrollableScrollPhysics(), |
||||
|
shrinkWrap: true, |
||||
|
itemCount: 10, |
||||
); |
); |
||||
} |
} |
||||
} |
} |
@ -0,0 +1,28 @@ |
|||||
|
import 'package:data/app_setting_data/repository/app_setting_box_repository_impl.dart'; |
||||
|
import 'package:flutter_bloc/flutter_bloc.dart'; |
||||
|
import 'package:local_db_core/lib/boxes/box_list/setting_box/app_setting_box.dart'; |
||||
|
import 'package:repositories/app_setting_box_domain/repository/app_setting_box_repository.dart'; |
||||
|
import 'package:sonnat/core/utils/base_cubit_type.dart'; |
||||
|
|
||||
|
class SplashCubit extends Cubit<BaseCubitType<SplashCubitState>> { |
||||
|
final AppSettingBoxRepository _repository = AppSettingBoxRepositoryImpl(appSettingBox: AppSettingBox()); |
||||
|
|
||||
|
SplashCubit() : super(BaseCubitType(eventName: SplashCubitState.empty)); |
||||
|
|
||||
|
void empty() => emit(BaseCubitType(eventName: SplashCubitState.empty)); |
||||
|
|
||||
|
Future<void> checkLanguageSet() async { |
||||
|
String? language = _repository.getCurrentLanguage(); |
||||
|
if(language == null || language == '') { |
||||
|
emit(BaseCubitType(eventName: SplashCubitState.notSet)); |
||||
|
} else { |
||||
|
emit(BaseCubitType(eventName: SplashCubitState.set)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
enum SplashCubitState { |
||||
|
empty, |
||||
|
set, |
||||
|
notSet, |
||||
|
} |
@ -0,0 +1,83 @@ |
|||||
|
import 'package:flutter/material.dart'; |
||||
|
import 'package:flutter_bloc/flutter_bloc.dart'; |
||||
|
import 'package:sonnat/core/extensions/context_extension.dart'; |
||||
|
import 'package:sonnat/core/extensions/string_extension.dart'; |
||||
|
import 'package:sonnat/core/select_language/cubit/select_language_cubit.dart'; |
||||
|
import 'package:sonnat/core/select_language/screen/select_language_screen.dart'; |
||||
|
import 'package:sonnat/core/utils/app_constants.dart'; |
||||
|
import 'package:sonnat/core/utils/base_cubit_type.dart'; |
||||
|
import 'package:sonnat/features/main/main_screen.dart'; |
||||
|
import 'package:sonnat/features/splash/cubit/splash_cubit.dart'; |
||||
|
|
||||
|
class SplashScreen extends StatefulWidget { |
||||
|
const SplashScreen({super.key}); |
||||
|
|
||||
|
@override |
||||
|
State<SplashScreen> createState() => _SplashScreenState(); |
||||
|
} |
||||
|
|
||||
|
class _SplashScreenState extends State<SplashScreen> { |
||||
|
late final SplashCubit _cubit; |
||||
|
|
||||
|
@override |
||||
|
void initState() { |
||||
|
_cubit = BlocProvider.of<SplashCubit>(context); |
||||
|
Future.delayed(const Duration(milliseconds: 2500), _cubit.checkLanguageSet); |
||||
|
super.initState(); |
||||
|
} |
||||
|
|
||||
|
@override |
||||
|
Widget build(BuildContext context) { |
||||
|
return Scaffold( |
||||
|
backgroundColor: const Color(0xff26237A), |
||||
|
body: BlocBuilder<SplashCubit, BaseCubitType<SplashCubitState>>( |
||||
|
builder: (context, state) { |
||||
|
switch (state.eventName!) { |
||||
|
case SplashCubitState.empty: |
||||
|
break; |
||||
|
case SplashCubitState.set: |
||||
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { |
||||
|
Navigator.push( |
||||
|
context, |
||||
|
MaterialPageRoute( |
||||
|
builder: (context) { |
||||
|
return const MainScreen(); |
||||
|
}, |
||||
|
), |
||||
|
); |
||||
|
}); |
||||
|
break; |
||||
|
case SplashCubitState.notSet: |
||||
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { |
||||
|
Navigator.push( |
||||
|
context, |
||||
|
MaterialPageRoute( |
||||
|
builder: (context) { |
||||
|
return BlocProvider( |
||||
|
create: (context) => SelectLanguageCubit(), |
||||
|
child: const SelectLanguageScreen(), |
||||
|
); |
||||
|
}, |
||||
|
), |
||||
|
); |
||||
|
}); |
||||
|
break; |
||||
|
} |
||||
|
return Center( |
||||
|
child: Container( |
||||
|
margin: EdgeInsets.only( |
||||
|
left: context.width * 86 / AppConstants.instance.appWidth, |
||||
|
right: context.width * 86 / AppConstants.instance.appWidth, |
||||
|
), |
||||
|
child: Image.asset( |
||||
|
'ic_main_header'.pngPath, |
||||
|
width: context.width * 200 / AppConstants.instance.appWidth, |
||||
|
height: context.height * 200 / AppConstants.instance.appHeight, |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
}, |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
} |