Merge pull request 'splash_scren' (#156) from splash_scren into main
Reviewed-on: https://repo.ravanertebat.com/TM/tm_app/pulls/156
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
@@ -4,6 +4,7 @@ class AssetsManager {
|
|||||||
//logo
|
//logo
|
||||||
static const logoSmall = 'assets/icons/logo_small.svg';
|
static const logoSmall = 'assets/icons/logo_small.svg';
|
||||||
static const logoBig = 'assets/icons/logo_big.svg';
|
static const logoBig = 'assets/icons/logo_big.svg';
|
||||||
|
static const logoBigPng = 'assets/pngs/logo-big.png';
|
||||||
|
|
||||||
//bottom navigation
|
//bottom navigation
|
||||||
static const homeActive = 'assets/icons/home_active.svg';
|
static const homeActive = 'assets/icons/home_active.svg';
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import '../../views/final_completion_of_documents/pages/final_completion_of_docu
|
|||||||
import '../../views/forgot_password/pages/forgot_password_screen.dart';
|
import '../../views/forgot_password/pages/forgot_password_screen.dart';
|
||||||
import '../../views/notification/pages/notification_screen.dart';
|
import '../../views/notification/pages/notification_screen.dart';
|
||||||
import '../../views/profile/pages/profile_screen.dart';
|
import '../../views/profile/pages/profile_screen.dart';
|
||||||
|
import '../../views/splash/pages/splash_screen.dart';
|
||||||
import '../../views/tenders/pages/tenders_screen.dart';
|
import '../../views/tenders/pages/tenders_screen.dart';
|
||||||
import '../../views/your_tenders/pages/your_tenders_screen.dart';
|
import '../../views/your_tenders/pages/your_tenders_screen.dart';
|
||||||
import 'app_shell/app_shell_screen.dart';
|
import 'app_shell/app_shell_screen.dart';
|
||||||
@@ -31,7 +32,7 @@ final GlobalKey<NavigatorState> notificationNavigatorKey =
|
|||||||
// Main app router
|
// Main app router
|
||||||
final GoRouter appRouter = GoRouter(
|
final GoRouter appRouter = GoRouter(
|
||||||
routes: $appRoutes,
|
routes: $appRoutes,
|
||||||
initialLocation: '/login',
|
initialLocation: '/splash',
|
||||||
navigatorKey: rootNavigatorKey,
|
navigatorKey: rootNavigatorKey,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -46,6 +47,17 @@ class LoginScreenRoute extends GoRouteData with _$LoginScreenRoute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// splash route - outside the shell
|
||||||
|
@TypedGoRoute<SplashScreenRoute>(path: '/splash')
|
||||||
|
class SplashScreenRoute extends GoRouteData with _$SplashScreenRoute {
|
||||||
|
const SplashScreenRoute();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, GoRouterState state) {
|
||||||
|
return const SplashScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Shell route with bottom navigation using StatefulShellRoute.indexedStack
|
// Shell route with bottom navigation using StatefulShellRoute.indexedStack
|
||||||
@TypedStatefulShellRoute<AppShellRouteData>(
|
@TypedStatefulShellRoute<AppShellRouteData>(
|
||||||
branches: <TypedStatefulShellBranch<StatefulShellBranchData>>[
|
branches: <TypedStatefulShellBranch<StatefulShellBranchData>>[
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ part of 'app_routes.dart';
|
|||||||
|
|
||||||
List<RouteBase> get $appRoutes => [
|
List<RouteBase> get $appRoutes => [
|
||||||
$loginScreenRoute,
|
$loginScreenRoute,
|
||||||
|
$splashScreenRoute,
|
||||||
$appShellRouteData,
|
$appShellRouteData,
|
||||||
$yourTendersRouteData,
|
$yourTendersRouteData,
|
||||||
$finalCompletionOfDocumentsRouteData,
|
$finalCompletionOfDocumentsRouteData,
|
||||||
@@ -43,6 +44,33 @@ mixin _$LoginScreenRoute on GoRouteData {
|
|||||||
void replace(BuildContext context) => context.replace(location);
|
void replace(BuildContext context) => context.replace(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RouteBase get $splashScreenRoute => GoRouteData.$route(
|
||||||
|
path: '/splash',
|
||||||
|
|
||||||
|
factory: _$SplashScreenRoute._fromState,
|
||||||
|
);
|
||||||
|
|
||||||
|
mixin _$SplashScreenRoute on GoRouteData {
|
||||||
|
static SplashScreenRoute _fromState(GoRouterState state) =>
|
||||||
|
const SplashScreenRoute();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get location => GoRouteData.$location('/splash');
|
||||||
|
|
||||||
|
@override
|
||||||
|
void go(BuildContext context) => context.go(location);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<T?> push<T>(BuildContext context) => context.push<T>(location);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void pushReplacement(BuildContext context) =>
|
||||||
|
context.pushReplacement(location);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(BuildContext context) => context.replace(location);
|
||||||
|
}
|
||||||
|
|
||||||
RouteBase get $appShellRouteData => StatefulShellRouteData.$route(
|
RouteBase get $appShellRouteData => StatefulShellRouteData.$route(
|
||||||
parentNavigatorKey: AppShellRouteData.$parentNavigatorKey,
|
parentNavigatorKey: AppShellRouteData.$parentNavigatorKey,
|
||||||
factory: $AppShellRouteDataExtension._fromState,
|
factory: $AppShellRouteDataExtension._fromState,
|
||||||
|
|||||||
@@ -47,4 +47,8 @@ class AuthRepository {
|
|||||||
}) async {
|
}) async {
|
||||||
return _authService.verifyOtp(code: code, email: email);
|
return _authService.verifyOtp(code: code, email: email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Result<bool>> checkIsLoggedIn() async {
|
||||||
|
return _authService.checkIsLoggedIn();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,4 +113,13 @@ class AuthService {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Result<bool>> checkIsLoggedIn() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
final token = prefs.getString('bearer');
|
||||||
|
if (token == null) {
|
||||||
|
return const Result.ok(false);
|
||||||
|
}
|
||||||
|
return const Result.ok(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -230,8 +230,8 @@ class $AssetsPngsGen {
|
|||||||
AssetGenImage get forgotPassword =>
|
AssetGenImage get forgotPassword =>
|
||||||
const AssetGenImage('assets/pngs/forgot_password.png');
|
const AssetGenImage('assets/pngs/forgot_password.png');
|
||||||
|
|
||||||
/// File path: assets/pngs/logo.png
|
/// File path: assets/pngs/logo-big.png
|
||||||
AssetGenImage get logo => const AssetGenImage('assets/pngs/logo.png');
|
AssetGenImage get logoBig => const AssetGenImage('assets/pngs/logo-big.png');
|
||||||
|
|
||||||
/// File path: assets/pngs/web_login_image.png
|
/// File path: assets/pngs/web_login_image.png
|
||||||
AssetGenImage get webLoginImage =>
|
AssetGenImage get webLoginImage =>
|
||||||
@@ -241,7 +241,7 @@ class $AssetsPngsGen {
|
|||||||
List<AssetGenImage> get values => [
|
List<AssetGenImage> get values => [
|
||||||
appLogo,
|
appLogo,
|
||||||
forgotPassword,
|
forgotPassword,
|
||||||
logo,
|
logoBig,
|
||||||
webLoginImage,
|
webLoginImage,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class AuthViewModel with ChangeNotifier {
|
|||||||
|
|
||||||
// Auth state
|
// Auth state
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
|
bool _isLoggedIn = false;
|
||||||
bool _isResetPasswordLoading = false;
|
bool _isResetPasswordLoading = false;
|
||||||
String? _errorMessage;
|
String? _errorMessage;
|
||||||
String? _resetPasswordErrorMessage;
|
String? _resetPasswordErrorMessage;
|
||||||
@@ -59,6 +60,7 @@ class AuthViewModel with ChangeNotifier {
|
|||||||
bool _verifyOtpSuccess = false;
|
bool _verifyOtpSuccess = false;
|
||||||
|
|
||||||
bool get isLoading => _isLoading;
|
bool get isLoading => _isLoading;
|
||||||
|
bool get isLoggedIn => _isLoggedIn;
|
||||||
bool get isLoadingForgot => _isLoadingForgot;
|
bool get isLoadingForgot => _isLoadingForgot;
|
||||||
bool get isLoadingOtp => _isLoadingOtp;
|
bool get isLoadingOtp => _isLoadingOtp;
|
||||||
bool get isResetPasswordLoading => _isResetPasswordLoading;
|
bool get isResetPasswordLoading => _isResetPasswordLoading;
|
||||||
@@ -282,6 +284,21 @@ class AuthViewModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> checkIsLoggedIn() async {
|
||||||
|
final result = await _authRepository.checkIsLoggedIn();
|
||||||
|
|
||||||
|
if (result is Ok<bool>) {
|
||||||
|
if (result.value) {
|
||||||
|
_isLoggedIn = result.value;
|
||||||
|
} else {
|
||||||
|
_isLoggedIn = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_isLoggedIn = false;
|
||||||
|
}
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
void clearResetPasswordSuccess() {
|
void clearResetPasswordSuccess() {
|
||||||
_resetPasswordSuccess = false;
|
_resetPasswordSuccess = false;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tm_app/core/routes/app_routes.dart';
|
||||||
|
import 'package:tm_app/view_models/auth_view_model.dart';
|
||||||
|
|
||||||
|
import '../../../core/constants/assets.dart';
|
||||||
|
|
||||||
|
class DesktopSplashPage extends StatefulWidget {
|
||||||
|
const DesktopSplashPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DesktopSplashPage> createState() => _DesktopSplashPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DesktopSplashPageState extends State<DesktopSplashPage> {
|
||||||
|
late final AuthViewModel viewModel;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
viewModel = context.read<AuthViewModel>();
|
||||||
|
Future.delayed(const Duration(seconds: 1), () async {
|
||||||
|
await viewModel.checkIsLoggedIn();
|
||||||
|
});
|
||||||
|
viewModel.addListener(_viewModelListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
viewModel.removeListener(_viewModelListener);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _viewModelListener() {
|
||||||
|
if (viewModel.isLoggedIn) {
|
||||||
|
Router.neglect(context, () => const HomeRouteData().go(context));
|
||||||
|
} else {
|
||||||
|
Router.neglect(context, () => const LoginScreenRoute().go(context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 100),
|
||||||
|
child: Image.asset(AssetsManager.logoBigPng),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tm_app/core/constants/assets.dart';
|
||||||
|
import 'package:tm_app/core/routes/app_routes.dart';
|
||||||
|
import 'package:tm_app/core/utils/size_config.dart';
|
||||||
|
import 'package:tm_app/view_models/auth_view_model.dart';
|
||||||
|
|
||||||
|
class MobileSplashPage extends StatefulWidget {
|
||||||
|
const MobileSplashPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MobileSplashPage> createState() => _MobileSplashPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MobileSplashPageState extends State<MobileSplashPage> {
|
||||||
|
late final AuthViewModel viewModel;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
viewModel = context.read<AuthViewModel>();
|
||||||
|
Future.delayed(const Duration(seconds: 1), () async {
|
||||||
|
await viewModel.checkIsLoggedIn();
|
||||||
|
});
|
||||||
|
viewModel.addListener(_viewModelListener);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _viewModelListener() {
|
||||||
|
if (viewModel.isLoggedIn) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
Router.neglect(context, () => const HomeRouteData().go(context));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
Router.neglect(context, () => const LoginScreenRoute().go(context));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
viewModel.removeListener(_viewModelListener);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 24.0.w()),
|
||||||
|
child: Image.asset(AssetsManager.logoBigPng, fit: BoxFit.cover),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:tm_app/core/utils/size_config.dart';
|
||||||
|
import 'package:tm_app/views/shared/responsive_builder.dart';
|
||||||
|
import 'package:tm_app/views/splash/pages/d_splash_page.dart';
|
||||||
|
import 'package:tm_app/views/splash/pages/m_splash_page.dart';
|
||||||
|
import 'package:tm_app/views/splash/pages/t_splash_page.dart';
|
||||||
|
|
||||||
|
class SplashScreen extends StatelessWidget {
|
||||||
|
const SplashScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
SizeConfig.init(context);
|
||||||
|
return const ResponsiveBuilder(
|
||||||
|
mobile: MobileSplashPage(),
|
||||||
|
tablet: TabletSplashPage(),
|
||||||
|
desktop: DesktopSplashPage(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tm_app/view_models/auth_view_model.dart';
|
||||||
|
|
||||||
|
import '../../../core/constants/assets.dart';
|
||||||
|
import '../../../core/routes/app_routes.dart';
|
||||||
|
|
||||||
|
class TabletSplashPage extends StatefulWidget {
|
||||||
|
const TabletSplashPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<TabletSplashPage> createState() => _TabletSplashPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TabletSplashPageState extends State<TabletSplashPage> {
|
||||||
|
late final AuthViewModel viewModel;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
viewModel = context.read<AuthViewModel>();
|
||||||
|
Future.delayed(const Duration(seconds: 1), () async {
|
||||||
|
await viewModel.checkIsLoggedIn();
|
||||||
|
});
|
||||||
|
viewModel.addListener(_viewModelListener);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _viewModelListener() {
|
||||||
|
if (viewModel.isLoggedIn) {
|
||||||
|
Router.neglect(context, () => const HomeRouteData().go(context));
|
||||||
|
} else {
|
||||||
|
Router.neglect(context, () => const LoginScreenRoute().go(context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
viewModel.removeListener(_viewModelListener);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 40),
|
||||||
|
child: Image.asset(AssetsManager.logoBigPng),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-8
@@ -45,10 +45,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
|
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.12.0"
|
version: "2.13.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -269,10 +269,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.3.3"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -572,10 +572,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
|
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.8"
|
version: "10.0.9"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1049,10 +1049,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
|
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.3.1"
|
version: "15.0.0"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
Reference in New Issue
Block a user