FCSC Feedback bug fix
This commit is contained in:
parent
4da8888796
commit
10f8ab2db0
@ -20,12 +20,12 @@ if (project.hasProperty('google-services.json')) {
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = "25"
|
||||
flutterVersionCode = "26"
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty("flutter.versionName")
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = "1.2.17"
|
||||
flutterVersionName = "1.2.18"
|
||||
}
|
||||
|
||||
def keystorePropertiesFile = rootProject.file("key.properties")
|
||||
|
||||
@ -513,7 +513,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.2.15;
|
||||
MARKETING_VERSION = 1.2.16;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ae.gov.fcsc.frontend.ios;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
@ -707,7 +707,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.2.15;
|
||||
MARKETING_VERSION = 1.2.16;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ae.gov.fcsc.frontend.ios;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
@ -737,7 +737,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.2.15;
|
||||
MARKETING_VERSION = 1.2.16;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = ae.gov.fcsc.frontend.ios;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// api_config.dart
|
||||
// const String apiUrl = 'http://127.0.0.1:8090';
|
||||
// const String apiUrl = 'https://pbdev.venbait.in/';
|
||||
// const String apiUrl = 'https://pb.venbait.in/';
|
||||
const String apiUrl = 'https://pocket.fcsc.gov.ae/';
|
||||
const String apiUrl = 'https://pb.venbait.in/';
|
||||
// const String apiUrl = 'https://pocket.fcsc.gov.ae/';
|
||||
|
||||
@ -11,7 +11,7 @@ class AuthRepository {
|
||||
Future<String?> fetchLocallyStored() async {
|
||||
return await _secureStorage.read(key: "FlutterSecureStorage.session");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SessionCheckScreen extends StatefulWidget {
|
||||
const SessionCheckScreen({Key? key}) : super(key: key);
|
||||
@ -25,6 +25,14 @@ class _SessionCheckScreenState extends State<SessionCheckScreen> {
|
||||
final String playStoreUrl = "https://play.google.com/store/apps/details?id=ae.gov.fcsc.stats";
|
||||
bool _isLoading = true;
|
||||
|
||||
bool _isLoginPath(String path) {
|
||||
return path == '/login' || path.startsWith('/login?');
|
||||
}
|
||||
|
||||
bool _isForgotPasswordPath(String path) {
|
||||
return path.startsWith('/forgot-password/');
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@ -43,20 +51,34 @@ class _SessionCheckScreenState extends State<SessionCheckScreen> {
|
||||
.uri;
|
||||
|
||||
final intendedPath = uri.queryParameters['intendedPath'];
|
||||
final normalizedIntendedPath =
|
||||
(intendedPath != null && intendedPath.isNotEmpty)
|
||||
? Uri.decodeComponent(intendedPath)
|
||||
: null;
|
||||
|
||||
if (session != null &&
|
||||
session.freshness != SessionFreshness.expired) {
|
||||
|
||||
if (intendedPath != null && intendedPath.isNotEmpty) {
|
||||
context.go(intendedPath);
|
||||
if (normalizedIntendedPath != null && normalizedIntendedPath.isNotEmpty) {
|
||||
// Deep link to /login should open home when session is already valid.
|
||||
if (_isLoginPath(normalizedIntendedPath)) {
|
||||
context.go('/myhomepage');
|
||||
} else {
|
||||
context.go(normalizedIntendedPath);
|
||||
}
|
||||
} else {
|
||||
context.go('/myhomepage');
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (intendedPath != null && intendedPath.isNotEmpty) {
|
||||
context.go('/login?intendedPath=${Uri.encodeComponent(intendedPath)}');
|
||||
if (normalizedIntendedPath != null && normalizedIntendedPath.isNotEmpty) {
|
||||
// Forgot password links are public and should open directly.
|
||||
if (_isForgotPasswordPath(normalizedIntendedPath)) {
|
||||
context.go(normalizedIntendedPath);
|
||||
} else {
|
||||
context.go('/login?intendedPath=${Uri.encodeComponent(normalizedIntendedPath)}');
|
||||
}
|
||||
} else {
|
||||
context.go('/login');
|
||||
}
|
||||
|
||||
@ -50,34 +50,95 @@ class _ThemeSelectorDialogState extends State<ThemeSelectorDialog> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDarkTheme = Theme.of(context).brightness == Brightness.dark;
|
||||
const accentColor = Color(0xFFB68A34);
|
||||
|
||||
return AlertDialog(
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
title: Text(
|
||||
_tr(en: 'Choose Theme', ar: 'اختر المظهر'),
|
||||
style: TextStyle(
|
||||
color: isDarkTheme ? Colors.white : Colors.black,
|
||||
),
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: AppTheme.values.map((theme) {
|
||||
return RadioListTile<AppTheme>(
|
||||
title: Text(_themeLabel(theme)),
|
||||
value: theme,
|
||||
groupValue: _selectedTheme,
|
||||
onChanged: (value) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(
|
||||
'ThemeType', value.toString().split('.').last);
|
||||
content: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: AppTheme.values.map((theme) {
|
||||
return RadioListTile<AppTheme>(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
activeColor: accentColor,
|
||||
fillColor: WidgetStateProperty.all(accentColor),
|
||||
title: Text(
|
||||
_themeLabel(theme),
|
||||
style: TextStyle(
|
||||
color: isDarkTheme ? Colors.white : Colors.black,
|
||||
),
|
||||
),
|
||||
value: theme,
|
||||
groupValue: _selectedTheme,
|
||||
onChanged: (value) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(
|
||||
'ThemeType', value.toString().split('.').last);
|
||||
|
||||
setState(() => _selectedTheme = value!);
|
||||
});
|
||||
}).toList(),
|
||||
setState(() => _selectedTheme = value!);
|
||||
});
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(null),
|
||||
child: Text(_tr(en: 'Cancel', ar: 'إلغاء')),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.of(context).pop(_selectedTheme),
|
||||
child: Text(_tr(en: 'OK', ar: 'حسناً')),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(null),
|
||||
style: TextButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
side: const BorderSide(
|
||||
color: accentColor,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
_tr(en: 'Cancel', ar: 'إلغاء'),
|
||||
style: const TextStyle(
|
||||
color: accentColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(_selectedTheme),
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: accentColor,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
),
|
||||
child: FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
child: Text(
|
||||
_tr(en: 'OK', ar: 'حسناً'),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@ -92,6 +92,7 @@ class _MainAppState extends ConsumerState<MainApp> {
|
||||
String? pendingDeepLink;
|
||||
Map<String, dynamic>? pendingDeepLinkData;
|
||||
StreamSubscription<Uri>? _appLinkSubscription;
|
||||
Timer? _oneLinkFallbackTimer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -104,6 +105,7 @@ class _MainAppState extends ConsumerState<MainApp> {
|
||||
@override
|
||||
void dispose() {
|
||||
_appLinkSubscription?.cancel();
|
||||
_oneLinkFallbackTimer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -123,8 +125,15 @@ class _MainAppState extends ConsumerState<MainApp> {
|
||||
if (uri.scheme == 'fcscappstates') {
|
||||
final deepLinkValue = uri.queryParameters['deep_link_value'];
|
||||
if (deepLinkValue != null && deepLinkValue.isNotEmpty) {
|
||||
_oneLinkFallbackTimer?.cancel();
|
||||
final path = deepLinkValue.startsWith('/') ? deepLinkValue : '/$deepLinkValue';
|
||||
router.go('/?intendedPath=${Uri.encodeComponent(path)}');
|
||||
} else {
|
||||
// Wait briefly for AppsFlyer SDK callback, then fallback to app root.
|
||||
_oneLinkFallbackTimer?.cancel();
|
||||
_oneLinkFallbackTimer = Timer(const Duration(milliseconds: 1500), () {
|
||||
if (mounted) router.go('/');
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -133,8 +142,17 @@ class _MainAppState extends ConsumerState<MainApp> {
|
||||
if (uri.scheme == 'https' && uri.host == 'fcscstats.onelink.me') {
|
||||
final deepLinkValue = uri.queryParameters['deep_link_value'];
|
||||
if (deepLinkValue != null && deepLinkValue.isNotEmpty) {
|
||||
_oneLinkFallbackTimer?.cancel();
|
||||
final path = deepLinkValue.startsWith('/') ? deepLinkValue : '/$deepLinkValue';
|
||||
router.go('/?intendedPath=${Uri.encodeComponent(path)}');
|
||||
} else {
|
||||
// Some OneLink opens arrive without query params; AppsFlyer SDK usually
|
||||
// delivers deep_link_value shortly after. Delay root fallback to avoid
|
||||
// overriding the real deep-link route.
|
||||
_oneLinkFallbackTimer?.cancel();
|
||||
_oneLinkFallbackTimer = Timer(const Duration(milliseconds: 1500), () {
|
||||
if (mounted) router.go('/');
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -204,13 +222,37 @@ class _MainAppState extends ConsumerState<MainApp> {
|
||||
}
|
||||
|
||||
void _handleDeepLink(String? deepLinkValue, Map<String, dynamic> data) {
|
||||
if (deepLinkValue == null || deepLinkValue.isEmpty) return;
|
||||
_oneLinkFallbackTimer?.cancel();
|
||||
|
||||
String? resolved = deepLinkValue;
|
||||
|
||||
// AppsFlyer may not always populate deepLinkValue for complex links.
|
||||
// Fallback to clickEvent payload keys.
|
||||
resolved ??= data['deep_link_value']?.toString();
|
||||
resolved ??= data['af_dp']?.toString();
|
||||
resolved = resolved?.trim();
|
||||
|
||||
if (resolved == null || resolved.isEmpty) return;
|
||||
|
||||
// If AppsFlyer gives a full URL, preserve path+query only.
|
||||
if (resolved.startsWith('http://') || resolved.startsWith('https://')) {
|
||||
final parsed = Uri.tryParse(resolved);
|
||||
if (parsed != null) {
|
||||
resolved = parsed.path + (parsed.hasQuery ? '?${parsed.query}' : '');
|
||||
}
|
||||
}
|
||||
|
||||
// Decode once so encoded query paths like
|
||||
// %2FchartScreen%2Fgdp%3FbgColor%3D... become route-friendly.
|
||||
try {
|
||||
resolved = Uri.decodeComponent(resolved);
|
||||
} catch (_) {}
|
||||
|
||||
// Use full path as intendedPath so shared links (e.g. /uaenumbers/123) open the right screen.
|
||||
// SessionCheckScreen: if logged in -> go to intendedPath; if not -> login then redirect.
|
||||
final String intendedPath = deepLinkValue.startsWith('/')
|
||||
? deepLinkValue
|
||||
: '/$deepLinkValue';
|
||||
final String intendedPath = resolved!.startsWith('/')
|
||||
? resolved
|
||||
: '/$resolved';
|
||||
|
||||
context.go('/?intendedPath=${Uri.encodeComponent(intendedPath)}');
|
||||
}
|
||||
|
||||
@ -2370,7 +2370,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
||||
// OneLink template V6mR; configure in AppsFlyer dashboard: app package/bundle ID + store fallback URLs
|
||||
const String baseAppLink = 'https://fcscstats.onelink.me/V6mR/t40b32al';
|
||||
final String path = currentRoute.startsWith('/') ? currentRoute : '/$currentRoute';
|
||||
final String shareLink = path == '/' ? baseAppLink : '$baseAppLink$path';
|
||||
final String shareLink = path == '/'
|
||||
? baseAppLink
|
||||
: '$baseAppLink?deep_link_value=${Uri.encodeComponent(path)}';
|
||||
final String shareText = 'Check this out!\n\n$shareLink';
|
||||
print('Generated Share Link: $shareLink');
|
||||
|
||||
|
||||
@ -229,29 +229,29 @@ class LoginRoute extends HookConsumerWidget with WidgetsBindingObserver{
|
||||
backgroundColor: isDark ? const Color(0xFF1F1F1F) : Colors.white,
|
||||
title: showErrorTitle
|
||||
? Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const CircleAvatar(
|
||||
radius: 18,
|
||||
backgroundColor: Color(0xFFFFE9E9),
|
||||
child: Icon(
|
||||
Icons.priority_high_rounded,
|
||||
color: Color(0xFFD83731),
|
||||
size: 22,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
context.translate('Error!', 'خطأ!'),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontFamily: context.translate('Roboto', 'NotoKufi'),
|
||||
fontWeight: FontWeight.w700,
|
||||
color: isDark ? Colors.white : const Color(0xFF1A1A1A),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const CircleAvatar(
|
||||
radius: 18,
|
||||
backgroundColor: Color(0xFFFFE9E9),
|
||||
child: Icon(
|
||||
Icons.priority_high_rounded,
|
||||
color: Color(0xFFD83731),
|
||||
size: 22,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
context.translate('Error!', 'خطأ!'),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontFamily: context.translate('Roboto', 'NotoKufi'),
|
||||
fontWeight: FontWeight.w700,
|
||||
color: isDark ? Colors.white : const Color(0xFF1A1A1A),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
content: Text(
|
||||
message,
|
||||
@ -674,11 +674,11 @@ class LoginRoute extends HookConsumerWidget with WidgetsBindingObserver{
|
||||
}
|
||||
|
||||
Future<void> oAuthGoogleAndAppleLogin(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
platform, {
|
||||
bool linkToExistingAccount = false,
|
||||
}) async {
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
platform, {
|
||||
bool linkToExistingAccount = false,
|
||||
}) async {
|
||||
print('platform $platform');
|
||||
try {
|
||||
final authData;
|
||||
@ -696,8 +696,9 @@ class LoginRoute extends HookConsumerWidget with WidgetsBindingObserver{
|
||||
queryParameters: {
|
||||
...url.queryParameters,
|
||||
'acr_values':
|
||||
'urn:safelayer:tws:policies:authentication:level:low',
|
||||
'urn:safelayer:tws:policies:authentication:level:low',
|
||||
'ui_locales': uiLocales,
|
||||
// 'redirect_url': 'ae.gov.fcsc.stats://auth-callback',
|
||||
},
|
||||
);
|
||||
print(mobileUri);
|
||||
@ -727,7 +728,7 @@ class LoginRoute extends HookConsumerWidget with WidgetsBindingObserver{
|
||||
// Google must use external browser. Apple uses OAuthWebView on mobile per app flow.
|
||||
authData = await pb.collection('users').authWithOAuth2(
|
||||
platform,
|
||||
(url) async {
|
||||
(url) async {
|
||||
if (platform == 'apple' && !kIsWeb) {
|
||||
if (!context.mounted) return;
|
||||
await Navigator.of(context).push(
|
||||
@ -2629,17 +2630,17 @@ class LoginRoute extends HookConsumerWidget with WidgetsBindingObserver{
|
||||
dontHaveAnAccountRegisterBtn,
|
||||
// continueAsGuestBtn,
|
||||
15.verticalSpace,
|
||||
// orText,
|
||||
// 15.verticalSpace,
|
||||
// signInWithUAEPassBtn,
|
||||
// 15.verticalSpace,
|
||||
// orText,
|
||||
orText,
|
||||
15.verticalSpace,
|
||||
signInWithUAEPassBtn,
|
||||
15.verticalSpace,
|
||||
orText,
|
||||
15.verticalSpace,
|
||||
signInWithGoogleBtn,
|
||||
15.verticalSpace,
|
||||
signInWithAppleBtn,
|
||||
15.verticalSpace,
|
||||
signInWithUAEPassBtn,
|
||||
// 15.verticalSpace,
|
||||
// signInWithUAEPassBtn,
|
||||
30.verticalSpace,
|
||||
// 120.verticalSpace,
|
||||
],
|
||||
@ -2791,29 +2792,48 @@ class OAuthWebView extends StatelessWidget {
|
||||
static const _resumePath = 'resume_authn';
|
||||
|
||||
Future<void> _closeIfOAuthCompleted(
|
||||
BuildContext context,
|
||||
InAppWebViewController controller,
|
||||
WebUri? url,
|
||||
) async {
|
||||
if (useUaePassDeepLink || !context.mounted) return;
|
||||
BuildContext context,
|
||||
InAppWebViewController controller,
|
||||
WebUri? url,
|
||||
) async {
|
||||
if (!context.mounted) return;
|
||||
|
||||
final s = (url?.toString() ?? '').toLowerCase();
|
||||
if (s.contains('/api/oauth2-redirect')) {
|
||||
Navigator.of(context).pop();
|
||||
final authIsReady = PocketBaseService.authStore.isValid;
|
||||
|
||||
if (s.contains('/api/oauth2-redirect') && s.contains('code=')) {
|
||||
await Navigator.of(context).maybePop();
|
||||
return;
|
||||
}
|
||||
|
||||
// PocketBase sometimes renders a static completion page.
|
||||
if (s.contains('oauth2-redirect-success') ||
|
||||
s.contains('oauth2_redirect_success')) {
|
||||
if (!useUaePassDeepLink && !authIsReady) return;
|
||||
await Navigator.of(context).maybePop();
|
||||
return;
|
||||
}
|
||||
|
||||
// PocketBase/hosted success pages (old + new titles).
|
||||
final title = ((await controller.getTitle()) ?? '').toLowerCase();
|
||||
if (title.contains('auth completed')) {
|
||||
Navigator.of(context).pop();
|
||||
if (title.contains('auth success') ||
|
||||
title.contains('auth completed') ||
|
||||
title.contains('authentication successful')) {
|
||||
if (!useUaePassDeepLink && !authIsReady) return;
|
||||
await Navigator.of(context).maybePop();
|
||||
return;
|
||||
}
|
||||
|
||||
final html = ((await controller.getHtml()) ?? '').toLowerCase();
|
||||
if (html.contains('auth completed') &&
|
||||
html.contains('you can close this window')) {
|
||||
Navigator.of(context).pop();
|
||||
final legacySuccess = html.contains('auth completed') &&
|
||||
(html.contains('you can close this window') ||
|
||||
html.contains('close this window'));
|
||||
final newSuccess = html.contains('authentication successful') &&
|
||||
(html.contains('proceed') ||
|
||||
html.contains('return to uae stats app'));
|
||||
|
||||
if (legacySuccess || newSuccess) {
|
||||
if (!useUaePassDeepLink && !authIsReady) return;
|
||||
await Navigator.of(context).maybePop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2828,13 +2848,29 @@ class OAuthWebView extends StatelessWidget {
|
||||
initialSettings: InAppWebViewSettings(
|
||||
javaScriptEnabled: true,
|
||||
domStorageEnabled: true,
|
||||
useShouldOverrideUrlLoading: useUaePassDeepLink,
|
||||
useShouldOverrideUrlLoading: true,
|
||||
),
|
||||
shouldOverrideUrlLoading: useUaePassDeepLink
|
||||
? (controller, navigationAction) async {
|
||||
shouldOverrideUrlLoading: (controller, navigationAction) async {
|
||||
final uri = navigationAction.request.url;
|
||||
if (uri == null) return NavigationActionPolicy.ALLOW;
|
||||
final full = uri.toString();
|
||||
|
||||
// If callback deep link is about to open, forward to OS and close WebView.
|
||||
if (full.toLowerCase().startsWith('$_appCallbackScheme://$_resumePath')) {
|
||||
final callbackUri = Uri.tryParse(full);
|
||||
if (callbackUri != null) {
|
||||
await launchUrl(callbackUri, mode: LaunchMode.externalApplication);
|
||||
}
|
||||
if (context.mounted) {
|
||||
await Navigator.of(context).maybePop();
|
||||
}
|
||||
return NavigationActionPolicy.CANCEL;
|
||||
}
|
||||
|
||||
if (!useUaePassDeepLink) {
|
||||
return NavigationActionPolicy.ALLOW;
|
||||
}
|
||||
|
||||
// Match uaepass:// or uaepassstg:// (scheme can be missing on some platforms)
|
||||
if (!full.toLowerCase().startsWith('$_uaepassProdScheme://') &&
|
||||
!full.toLowerCase().startsWith('$_uaepassStagingScheme://')) {
|
||||
@ -2875,12 +2911,11 @@ class OAuthWebView extends StatelessWidget {
|
||||
mode: LaunchMode.externalApplication,
|
||||
).then((launched) {
|
||||
if (launched && context.mounted) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).maybePop();
|
||||
}
|
||||
});
|
||||
return NavigationActionPolicy.CANCEL;
|
||||
}
|
||||
: null,
|
||||
},
|
||||
onLoadStart: (controller, url) async =>
|
||||
_closeIfOAuthCompleted(context, controller, url),
|
||||
onLoadStop: (controller, url) async =>
|
||||
@ -2891,7 +2926,7 @@ class OAuthWebView extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// abstract class _LocalAuthRepo {
|
||||
// static const _key = 'session';
|
||||
|
||||
@ -185,8 +185,8 @@ class _ReportDetailPageState extends ConsumerState<ReportDetailPage> {
|
||||
),
|
||||
child: BaseScaffold(
|
||||
showBackButton: true,
|
||||
backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
appbarColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.nav_competitiveness,
|
||||
style: TextStyle(
|
||||
@ -199,7 +199,8 @@ class _ReportDetailPageState extends ConsumerState<ReportDetailPage> {
|
||||
),
|
||||
body: isLoading || selectedReport.isEmpty
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: Column(
|
||||
: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
/// 🔹 Top Section With Padding
|
||||
Padding(
|
||||
@ -255,7 +256,7 @@ class _ReportDetailPageState extends ConsumerState<ReportDetailPage> {
|
||||
|
||||
/// 🔹 DESCRIPTION
|
||||
SizedBox(
|
||||
height: 72,
|
||||
height: 150,
|
||||
child: ScrollConfiguration(
|
||||
behavior: const ScrollBehavior().copyWith(scrollbars: false),
|
||||
child: SingleChildScrollView(
|
||||
@ -367,7 +368,9 @@ class _ReportDetailPageState extends ConsumerState<ReportDetailPage> {
|
||||
),
|
||||
|
||||
/// 🔹 COUNTRY SECTION
|
||||
Container(
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: isDarkTheme ? Color(0xFF222222) : Color(0xFFF5F5F5),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
@ -391,8 +394,11 @@ class _ReportDetailPageState extends ConsumerState<ReportDetailPage> {
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@ -155,8 +155,8 @@ class _CompetitivenessState extends ConsumerState<Competitiveness> {
|
||||
),
|
||||
),
|
||||
child: BaseScaffold(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
appbarColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.nav_competitiveness,
|
||||
style: TextStyle(
|
||||
|
||||
@ -199,8 +199,8 @@ class _DetailedCountryProfilePageState
|
||||
),
|
||||
),
|
||||
child: BaseScaffold(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
appbarColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.country_profile,
|
||||
style: TextStyle(
|
||||
@ -1069,7 +1069,7 @@ class _CategoryPopupContentState extends ConsumerState<CategoryPopupContent> {
|
||||
Text(
|
||||
tab['label'] as String,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: isDarkTheme
|
||||
? (isSelected
|
||||
@ -1084,7 +1084,7 @@ class _CategoryPopupContentState extends ConsumerState<CategoryPopupContent> {
|
||||
formatTradeValue(tab['total'] as double),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w900,
|
||||
fontSize: 22,
|
||||
fontSize: 16,
|
||||
color: _getTradeColor(typeKey),
|
||||
),
|
||||
),
|
||||
|
||||
@ -159,8 +159,8 @@ class _ListCountriesRouteState extends ConsumerState<ListCountriesRoute> {
|
||||
MediaQuery.of(context).platformBrightness == Brightness.dark);
|
||||
|
||||
final body = BaseScaffold(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
appbarColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.country_profile,
|
||||
style: TextStyle(
|
||||
@ -186,7 +186,7 @@ class _ListCountriesRouteState extends ConsumerState<ListCountriesRoute> {
|
||||
maxHeight: 50,
|
||||
),
|
||||
elevation: WidgetStatePropertyAll(0),
|
||||
backgroundColor: WidgetStatePropertyAll(isDarkTheme ? Color(0xFF111111) : Colors.white),
|
||||
backgroundColor: WidgetStatePropertyAll(isDarkTheme ? Colors.black : Colors.white),
|
||||
controller: _searchController,
|
||||
hintText: AppLocalizations.of(context)!.searchCountry,
|
||||
hintStyle: WidgetStateProperty.all(
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
@ -47,7 +48,7 @@ class UaeNumbers extends ConsumerWidget {
|
||||
context.go('/myhomepage'); // Show exit confirmation dialog
|
||||
},
|
||||
child: BaseScaffold(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF333333) : Color(0xFF414042),
|
||||
backgroundColor: isDarkTheme ? Color(0xFF000000) : Color(0xFFFFFFFF),
|
||||
title: Text(
|
||||
context.translate(
|
||||
'UAE Numbers',
|
||||
@ -63,6 +64,7 @@ class UaeNumbers extends ConsumerWidget {
|
||||
),
|
||||
body: uaenumberWidget(),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:pocketbase/pocketbase.dart';
|
||||
@ -60,7 +61,7 @@ class _MyHomePageState extends ConsumerState<MyHomePage> {
|
||||
'NotoKufi',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
content: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Text(
|
||||
@ -156,7 +157,7 @@ class _MyHomePageState extends ConsumerState<MyHomePage> {
|
||||
(ref.watch(themeProvider) == ThemeMode.system &&
|
||||
MediaQuery.of(context).platformBrightness == Brightness.dark);
|
||||
|
||||
return PopScope(
|
||||
return PopScope(
|
||||
canPop: false, // Allow back navigation only if not login screen
|
||||
onPopInvokedWithResult: (didPop, result) {
|
||||
if (didPop) return;
|
||||
@ -164,6 +165,7 @@ class _MyHomePageState extends ConsumerState<MyHomePage> {
|
||||
context, isDarkTheme); // Show exit confirmation dialog
|
||||
},
|
||||
child: BaseScaffold(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF000000) : Color(0xFFFFFFFF),
|
||||
title: Center(
|
||||
child: SizedBox(
|
||||
height: myheight / 5,
|
||||
@ -174,6 +176,7 @@ class _MyHomePageState extends ConsumerState<MyHomePage> {
|
||||
: LogoAssetPath.uaeStatLight)))),
|
||||
body: EconomyStatsWidget(),
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1078,8 +1081,9 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
return Center(child: Text("No data available"));
|
||||
}
|
||||
String firstMainTopic = data.first['main_topic'] ?? '';
|
||||
return Container(
|
||||
color: isDarkTheme ? Color(0xFF000000) : Color(0xFFFFFFFF),
|
||||
return SingleChildScrollView(
|
||||
child: Container(
|
||||
color: isDarkTheme ? Color(0xFF000000) : Color(0xFFFFFFFF),
|
||||
// decoration: isDarkTheme
|
||||
// ? BoxDecoration(
|
||||
// image: DecorationImage(
|
||||
@ -1088,12 +1092,12 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
// ),
|
||||
// )
|
||||
// : null,
|
||||
height: myheight,
|
||||
width: double.infinity,
|
||||
// color: Colors.cyan,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 10, right: 10),
|
||||
child: Column(
|
||||
children: data.map((mainTopic) {
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 10, right: 10),
|
||||
child: Column(
|
||||
children: data.map((mainTopic) {
|
||||
String colorPattern = mainTopic['color_pattern'];
|
||||
// Color backgroundColor = Color(int.parse(colorPattern));
|
||||
|
||||
@ -1121,11 +1125,9 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
final crossAxisCount =
|
||||
totalTiles > 0 ? (totalTiles / 2).ceil().clamp(1, 2) : 1;
|
||||
|
||||
return Expanded(
|
||||
child: Container(
|
||||
return Container(
|
||||
// color: Colors.cyan,
|
||||
height:
|
||||
myheight, // Set the background color for the entire Column
|
||||
// Set the background color for the entire Column
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -1205,9 +1207,9 @@ class EconomyStatsState extends ConsumerState<EconomyStatsWidget> {
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@ -519,8 +519,8 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
context.go('/myhomepage');
|
||||
},
|
||||
child: BaseScaffold(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
appbarColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.bookmarks,
|
||||
style: TextStyle(
|
||||
@ -532,7 +532,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
),
|
||||
body: isLoading
|
||||
? Container(
|
||||
color: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
color: isDarkTheme ? Colors.black : Colors.white,
|
||||
// color: Color(0x98FFFCE5), // Semi-transparent background
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -591,7 +591,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
childWidget: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: isDarkTheme
|
||||
? Color(0xFF111111)
|
||||
? Colors.black
|
||||
: Colors.white,
|
||||
// borderRadius: BorderRadius.all(Radius.circular(20))
|
||||
),
|
||||
@ -768,7 +768,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
height: 100,
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
decoration: BoxDecoration(
|
||||
color: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
color: isDarkTheme ? Colors.black : Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(color: data['valueColor']),
|
||||
),
|
||||
@ -892,7 +892,7 @@ class _BookMarkState extends ConsumerState<BookMark> {
|
||||
height: 100,
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
decoration: BoxDecoration(
|
||||
color: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
color: isDarkTheme ? Colors.black : Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(color: styleColor),
|
||||
),
|
||||
@ -985,7 +985,7 @@ class TabBarHeader extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
color: isDarkTheme ? Colors.black : Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
@ -1081,7 +1081,7 @@ class _CustomExpandableTileState extends State<CustomExpandableTile> {
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: widget.isDarkTheme
|
||||
? Color(0xFF111111)
|
||||
? Colors.black
|
||||
: Colors
|
||||
.white, // Ensuring the background outside the rounded container is white
|
||||
),
|
||||
|
||||
@ -143,13 +143,13 @@ class _ContactState extends ConsumerState<Contact> {
|
||||
context.go('/myhomepage');
|
||||
},
|
||||
child: BaseScaffold(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF333333) : Colors.white,
|
||||
appbarColor: isDarkTheme ? Color(0xFF333333) : Colors.white,
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
appbarColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
body: isLoading
|
||||
? Container(
|
||||
// color: Color(0x98FFFCE5), // Semi-transparent background
|
||||
color: isDarkTheme
|
||||
? Color(0xFF333333)
|
||||
? Colors.black
|
||||
: Color(0x98FFFCE5), // Semi-transparent background
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -171,7 +171,7 @@ class _ContactState extends ConsumerState<Contact> {
|
||||
: Container(
|
||||
// color: Colors.grey[200],
|
||||
// color: isDarkTheme ? Color(0xFF3B3C3F) : Colors.grey[200],
|
||||
color: isDarkTheme ? Color(0xFF333333) : Colors.grey[200],
|
||||
color: isDarkTheme ? Colors.black : Colors.grey[200],
|
||||
width: screenWidth,
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SingleChildScrollView(
|
||||
|
||||
@ -338,8 +338,8 @@ class _FeedbackFormState extends ConsumerState<FeedbackForm>
|
||||
context.go('/myhomepage'); // Show exit confirmation dialog
|
||||
},
|
||||
child: BaseScaffold(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
appbarColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
// backgroundColor: isDarkTheme ? Color(0xFF333333) : Color(0xFF414042),
|
||||
// appbarColor: isDarkTheme ? Color(0xFF333333) : Color(0xFF414042),
|
||||
|
||||
|
||||
@ -313,8 +313,8 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
|
||||
context.go('/myhomepage');
|
||||
},
|
||||
child: BaseScaffold(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
appbarColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
title: Text(
|
||||
context.translate(
|
||||
'Notification $notificationCount',
|
||||
@ -330,7 +330,7 @@ class _NotificationPageState extends ConsumerState<NotificationPage> {
|
||||
? Container(
|
||||
// color: Color(0x98FFFCE5), // Semi-transparent background
|
||||
color: isDarkTheme
|
||||
? Color(0xFF111111)
|
||||
? Colors.black
|
||||
: Color(0x98FFFCE5), // Semi-transparent background
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@ -435,7 +435,7 @@ class TabBarHeader extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
color: isDarkTheme ? Colors.black : Colors.white,
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
|
||||
@ -211,8 +211,8 @@ class _NotificationDetailsState extends ConsumerState<NotificationDetails> {
|
||||
context.go('/notification');
|
||||
},
|
||||
child: BaseScaffold(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
appbarColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
title: Text(
|
||||
context.translate(
|
||||
'Notification',
|
||||
|
||||
@ -99,15 +99,15 @@ class _UserguideState extends ConsumerState<Userguide> {
|
||||
},
|
||||
child: BaseScaffold(
|
||||
showDivider: true,
|
||||
bottomColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
bottomColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
// dividerColor: isDarkTheme ? Color(0xFF111111) : Colors.grey[300],
|
||||
dividerColor: isDarkTheme ? Colors.grey : Colors.grey[300],
|
||||
appbarColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
appbarColor: isDarkTheme ? Colors.black: Colors.white,
|
||||
title: Text(AppLocalizations.of(context)!.guide_title,
|
||||
style: TextStyle(
|
||||
color: isDarkTheme ? Colors.white : Color(0xFF414042))),
|
||||
body: Container(
|
||||
color: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
color: isDarkTheme ? Colors.black : Colors.white,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
|
||||
child: GridView.builder(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
@ -172,7 +172,7 @@ class _HoverContainerState extends ConsumerState<HoverContainer> {
|
||||
width: screenWidth * 0.30,
|
||||
margin: EdgeInsets.all(1),
|
||||
decoration: BoxDecoration(
|
||||
color: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
color: isDarkTheme ? Colors.black : Colors.white,
|
||||
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: isHovered
|
||||
|
||||
@ -1112,7 +1112,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
),
|
||||
),
|
||||
drawer: Drawer(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF111111) : Colors.white,
|
||||
backgroundColor: isDarkTheme ? Colors.black : Colors.white,
|
||||
child: Column(children: [
|
||||
Expanded(
|
||||
child: ListView(
|
||||
@ -1550,41 +1550,46 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
),
|
||||
),
|
||||
])),
|
||||
bottomNavigationBar: Stack(
|
||||
children: [
|
||||
// if (isDarkTheme)
|
||||
// Positioned(
|
||||
// bottom: 0,
|
||||
// left: 0,
|
||||
// right: 0,
|
||||
// child: Container(
|
||||
// height: kBottomNavigationBarHeight + 0, // Adjust as needed
|
||||
// decoration: BoxDecoration(
|
||||
// image: DecorationImage(
|
||||
// image: AssetImage(
|
||||
// 'assets/dark_bg.png'), // your dark mode image
|
||||
// fit: BoxFit.cover,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
BottomNavigationBar(
|
||||
bottomNavigationBar: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20),
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.10),
|
||||
blurRadius: 16,
|
||||
spreadRadius: 1,
|
||||
offset: const Offset(0, -2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20),
|
||||
),
|
||||
child: BottomNavigationBar(
|
||||
backgroundColor: isDarkTheme ? Color(0xFF000000) : Colors.white,
|
||||
currentIndex: _getSelectedIndex(currentRoute),
|
||||
onTap: (index) => _onItemTapped(context, index),
|
||||
type: BottomNavigationBarType.fixed,
|
||||
elevation: 0,
|
||||
items: [
|
||||
BottomNavigationBarItem(
|
||||
icon: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 4), // Adjust this for spacing
|
||||
child: Image.asset(
|
||||
BottomBarAssetIconPath.home,
|
||||
color: _getSelectedIndex(currentRoute) == 0
|
||||
? (isDarkTheme ? Color(0xFFFFFFFF) : Colors.black)
|
||||
: Color(0xFF989898),
|
||||
width: 23.98,
|
||||
height: 25,
|
||||
padding: const EdgeInsets.only(bottom: 4),
|
||||
child: SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: Image.asset(
|
||||
BottomBarAssetIconPath.home,
|
||||
fit: BoxFit.contain,
|
||||
color: _getSelectedIndex(currentRoute) == 0
|
||||
? Color(0xFFAA8E83)
|
||||
: Color(0xFF989898),
|
||||
),
|
||||
),
|
||||
),
|
||||
// label: 'Home',
|
||||
@ -1593,15 +1598,17 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
BottomNavigationBarItem(
|
||||
// icon: Icon(Icons.map),
|
||||
icon: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 4), // Adjust this for spacing
|
||||
child: Image.asset(
|
||||
BottomBarAssetIconPath.uaeMap,
|
||||
color: _getSelectedIndex(currentRoute) == 1
|
||||
? (isDarkTheme ? Color(0xFFFFFFFF) : Colors.black)
|
||||
: Color(0xFF989898),
|
||||
width: 23.98,
|
||||
height: 25,
|
||||
padding: const EdgeInsets.only(bottom: 4),
|
||||
child: SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: Image.asset(
|
||||
BottomBarAssetIconPath.uaeMap,
|
||||
fit: BoxFit.contain,
|
||||
color: _getSelectedIndex(currentRoute) == 1
|
||||
? Color(0xFFAA8E83)
|
||||
: Color(0xFF989898),
|
||||
),
|
||||
),
|
||||
),
|
||||
// label: 'UAE Numbers'
|
||||
@ -1609,15 +1616,17 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 4), // Adjust this for spacing
|
||||
child: Image.asset(
|
||||
BottomBarAssetIconPath.ranking,
|
||||
color: _getSelectedIndex(currentRoute) == 2
|
||||
? (isDarkTheme ? Color(0xFFFFFFFF) : Colors.black)
|
||||
: Color(0xFF989898),
|
||||
width: 23.98,
|
||||
height: 25,
|
||||
padding: const EdgeInsets.only(bottom: 4),
|
||||
child: SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: Image.asset(
|
||||
BottomBarAssetIconPath.ranking,
|
||||
fit: BoxFit.contain,
|
||||
color: _getSelectedIndex(currentRoute) == 2
|
||||
? Color(0xFFAA8E83)
|
||||
: Color(0xFF989898),
|
||||
),
|
||||
),
|
||||
),
|
||||
// label: 'Competitiveness',
|
||||
@ -1625,15 +1634,17 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 4), // Adjust this for spacing
|
||||
child: Image.asset(
|
||||
BottomBarAssetIconPath.globe,
|
||||
color: _getSelectedIndex(currentRoute) == 3
|
||||
? (isDarkTheme ? Color(0xFFFFFFFF) : Colors.black)
|
||||
: Color(0xFF989898),
|
||||
width: 23.98,
|
||||
height: 25,
|
||||
padding: const EdgeInsets.only(bottom: 4),
|
||||
child: SizedBox(
|
||||
width: 24,
|
||||
height: 24,
|
||||
child: Image.asset(
|
||||
BottomBarAssetIconPath.globe,
|
||||
fit: BoxFit.contain,
|
||||
color: _getSelectedIndex(currentRoute) == 3
|
||||
? Color(0xFFAA8E83)
|
||||
: Color(0xFF989898),
|
||||
),
|
||||
),
|
||||
),
|
||||
// label: 'Country Profile',
|
||||
@ -1641,7 +1652,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
),
|
||||
],
|
||||
key: bottomNavKey,
|
||||
selectedItemColor: isDarkTheme ? Color(0xFFFFFFFF) : Colors.black,
|
||||
selectedItemColor: Color(0xFFAA8E83),
|
||||
unselectedItemColor: Color(0xFF989898),
|
||||
selectedLabelStyle: TextStyle(
|
||||
fontFamily: context.translate(
|
||||
@ -1649,6 +1660,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
'NotoKufi',
|
||||
),
|
||||
fontSize: 10, // Font size for unselected label
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
unselectedLabelStyle: TextStyle(
|
||||
fontFamily: context.translate(
|
||||
@ -1659,7 +1671,7 @@ class _BaseScaffoldState extends ConsumerState<BaseScaffold> {
|
||||
),
|
||||
showUnselectedLabels: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// BottomNavigationBar(
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
name: uae_stat
|
||||
description: "View statistics about the UAE from the Federal Center for Statistics and Competitiveness."
|
||||
publish_to: "none"
|
||||
#version: 1.2.17+25
|
||||
version: 1.2.15+23
|
||||
#version: 1.2.18+26
|
||||
version: 1.2.16+24
|
||||
#version: 1.0.16+17
|
||||
#version: 1.0.6+6
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user