import 'dart:async'; // Add this import import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:hmg_qline/view_models/screen_config_view_model.dart'; import 'package:hmg_qline/views/common_widgets/app_general_widgets.dart'; import 'package:hmg_qline/views/common_widgets/date_display_widget.dart'; import 'package:hmg_qline/views/common_widgets/headline_tag_widget.dart'; import 'package:provider/provider.dart'; import 'package:hmg_qline/constants/app_constants.dart'; import 'package:hmg_qline/utilities/enums.dart'; import 'package:hmg_qline/views/common_widgets/app_texts_widget.dart'; import 'package:hmg_qline/views/view_helpers/size_config.dart'; class AppFooter extends StatefulWidget { const AppFooter({super.key}); @override State createState() => _AppFooterState(); } class _AppFooterState extends State { Timer? _timer; String _remainingTime = ""; @override void initState() { super.initState(); _startTimer(); } @override void dispose() { _timer?.cancel(); super.dispose(); } void _startTimer() { _timer = Timer.periodic(const Duration(seconds: 1), (timer) { if (mounted) { setState(() { _updateRemainingTime(); }); } }); _updateRemainingTime(); } void _updateRemainingTime() { final screenConfigVM = Provider.of(context, listen: false); final nextPrayerTimeStr = screenConfigVM.nextPrayerTime; if (nextPrayerTimeStr.isEmpty) { _remainingTime = ""; return; } try { final now = DateTime.now(); final timeParts = nextPrayerTimeStr.split(' '); final timeStr = timeParts[0]; final amPm = timeParts.length > 1 ? timeParts[1].toUpperCase() : 'AM'; final hourMin = timeStr.split(':'); int hour = int.parse(hourMin[0]); final minute = int.parse(hourMin[1]); if (amPm == 'PM' && hour != 12) { hour += 12; } else if (amPm == 'AM' && hour == 12) { hour = 0; } DateTime nextPrayer = DateTime(now.year, now.month, now.day, hour, minute); if (nextPrayer.isBefore(now)) { nextPrayer = nextPrayer.add(const Duration(days: 1)); } final difference = nextPrayer.difference(now); if (difference.isNegative) { _remainingTime = "00:00:00"; } else { final hours = difference.inHours; final minutes = difference.inMinutes % 60; final seconds = difference.inSeconds % 60; _remainingTime = "${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}"; } } catch (e) { _remainingTime = "00:00:00"; } } Widget _buildStatusRow(String label, bool isConnected) { return Row( children: [ AppText( "$label:", fontSize: SizeConfig.getWidthMultiplier()! * 1.5, ), AppText( " ${isConnected ? "Connected" : "Disconnected"}", fontSize: SizeConfig.getWidthMultiplier()! * 1.5, color: isConnected ? AppColors.greenColor : AppColors.redColor, ), ], ); } Widget _buildPrayerColumn(String label, String prayerName, {bool isForArabic = false}) { return Column( mainAxisSize: MainAxisSize.min, children: [ AppText( label, fontSize: SizeConfig.getWidthMultiplier()! * 1.5, fontFamily: isForArabic ? AppStrings.fontNameGesTwo : AppStrings.fontNamePoppins, ), AppText( prayerName, fontSize: SizeConfig.getWidthMultiplier()! * 1.8, fontWeight: FontWeight.bold, color: AppColors.darkGreyTextColor, fontFamily: isForArabic ? AppStrings.fontNameGesTwo : AppStrings.fontNamePoppins, ), ], ); } bool _isMoreThanOneHour(String timeString) { if (timeString.isEmpty) return false; try { final parts = timeString.split(':'); if (parts.length >= 3) { final hours = int.parse(parts[0]); return hours >= 1; } } catch (e) { return false; } return false; } String _getHoursFromTime(String timeString) { if (timeString.isEmpty) return "0"; try { final parts = timeString.split(':'); if (parts.length >= 3) { final hours = int.parse(parts[0]); final minutes = int.parse(parts[1]); if (minutes > 30) { return "${hours + 1}"; } return hours.toString(); } } catch (e) { return "0"; } return "0"; } bool _hasBothPrayerAndWeather(ScreenConfigViewModel screenConfigVM) { return screenConfigVM.globalConfigurationsModel.isPrayerTimeReq && screenConfigVM.globalConfigurationsModel.isWeatherReq; } bool _isPortraitWithBothFeatures(ScreenConfigViewModel screenConfigVM) { bool isPortrait = screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown; return isPortrait && _hasBothPrayerAndWeather(screenConfigVM); } Widget _buildConnectionStatus(ScreenConfigViewModel screenConfigVM) { bool isPortrait = screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown; EdgeInsets padding; if (_isPortraitWithBothFeatures(screenConfigVM)) { padding = EdgeInsets.only(top: SizeConfig.getHeightMultiplier()! * 0.15); } else if (isPortrait) { padding = EdgeInsets.only(top: SizeConfig.getHeightMultiplier()! * 0.3); } else { padding = EdgeInsets.only(top: SizeConfig.getHeightMultiplier()! * 0.15); } Widget content; if (_isPortraitWithBothFeatures(screenConfigVM)) { content = Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildStatusRow("Hub Status ", screenConfigVM.isHubConnected), SizedBox(height: SizeConfig.getHeightMultiplier()! * 0.05), _buildStatusRow("Network Status ", screenConfigVM.isInternetConnected), ], ); } else if (isPortrait) { content = Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildStatusRow("Hub Status ", screenConfigVM.isHubConnected), SizedBox(width: SizeConfig.getWidthMultiplier()! * 2), _buildStatusRow("Network Status ", screenConfigVM.isInternetConnected), ], ); } else { content = Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildStatusRow("Hub Status ", screenConfigVM.isHubConnected), SizedBox(height: SizeConfig.getHeightMultiplier()! * 0.05), _buildStatusRow("Network Status ", screenConfigVM.isInternetConnected), ], ); } return Padding(padding: padding, child: content); } Widget buildWeatherIcon(String? weatherIconPath) { if (weatherIconPath != null) { return SvgPicture.asset( weatherIconPath, height: SizeConfig.getHeightMultiplier() * 0.4, ); } return const SizedBox.shrink(); } Widget buildCurrentCityTemp(String? currentCity, String? temp, bool isForArabic) { return Column( mainAxisSize: MainAxisSize.min, children: [ if (temp != null) AppText( temp.toString(), fontSize: SizeConfig.getWidthMultiplier()! * 2, fontFamily: AppStrings.fontNamePoppins, fontWeight: FontWeight.bold, ), AppText( currentCity.toString(), fontSize: SizeConfig.getWidthMultiplier()! * 1.8, fontFamily: isForArabic ? AppStrings.fontNameGesTwo : AppStrings.fontNamePoppins, ), ], ); } Widget buildTempDetails(String? iconPhrase, double? maxTempText, double? minTempText, bool isForArabic) { return Column( mainAxisSize: MainAxisSize.min, children: [ SimpleDateDisplay(isForArabic: isForArabic), if (iconPhrase != null) AppText( iconPhrase, fontSize: SizeConfig.getWidthMultiplier()! * 1.5, fontFamily: AppStrings.fontNamePoppins, ), if (minTempText != null && maxTempText != null) AppText( "$minTempText°C / $maxTempText°C", fontSize: SizeConfig.getWidthMultiplier()! * 1.5, fontFamily: AppStrings.fontNamePoppins, fontWeight: FontWeight.bold, ), ], ); } @override Widget build(BuildContext context) { return Consumer( builder: (BuildContext context, ScreenConfigViewModel screenConfigVM, Widget? child) { bool isPortrait = screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitUp || screenConfigVM.globalConfigurationsModel.orientationTypeEnum == ScreenOrientationEnum.portraitDown; return Padding( padding: EdgeInsets.fromLTRB( SizeConfig.getWidthMultiplier() * 4, SizeConfig.getHeightMultiplier() * 0.14, 0, SizeConfig.getHeightMultiplier() * 0.05, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Padding( padding: EdgeInsets.only(right: SizeConfig.getWidthMultiplier() * 4), child: Row( children: [ Expanded( flex: screenConfigVM.globalConfigurationsModel.isWeatherReq && screenConfigVM.globalConfigurationsModel.isPrayerTimeReq ? 2 : 3, child: customShadowSmoothContainer( height: SizeConfig.getHeightMultiplier() * 0.8, padding: EdgeInsets.symmetric( horizontal: SizeConfig.getWidthMultiplier() * 3, vertical: SizeConfig.getHeightMultiplier() * 0.1, ), child: Row( crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Padding( padding: EdgeInsets.only(top: SizeConfig.getHeightMultiplier()! * 0.1), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ AppText( AppStrings.poweredBy, fontSize: SizeConfig.getWidthMultiplier()! * 1.5, fontWeight: FontWeight.w400, color: AppColors.darkGreyTextColor, ), AppText( "v${screenConfigVM.currentScreenIP.replaceAll(".", "").replaceAll("0", "-")}(${AppConstants.currentBuildVersion})", fontSize: SizeConfig.getWidthMultiplier()! * 1, fontWeight: FontWeight.w400, color: AppColors.darkGreyTextColor, ), ], ), ), SizedBox(width: SizeConfig.getWidthMultiplier()!), Padding( padding: EdgeInsets.only(bottom: SizeConfig.getHeightMultiplier()! * 0.06), child: Image.asset( AppAssets.cloudLogo, height: isPortrait ? SizeConfig.getHeightMultiplier()! * 0.6 : SizeConfig.getHeightMultiplier()! * 0.4, ), ), ], ), _buildConnectionStatus(screenConfigVM), ], ), ), ), if (screenConfigVM.globalConfigurationsModel.isPrayerTimeReq) ...[ SizedBox(width: SizeConfig.getWidthMultiplier()! * 1.7), Directionality( textDirection: screenConfigVM.globalConfigurationsModel.textDirection, child: Expanded( flex: 2, child: customShadowSmoothContainer( height: SizeConfig.getHeightMultiplier() * 0.8, padding: EdgeInsets.symmetric( horizontal: isPortrait ? SizeConfig.getWidthMultiplier() * 2.5 : SizeConfig.getWidthMultiplier() * 1.3, vertical: SizeConfig.getHeightMultiplier() * 0.1, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (isPortrait) ...[ SvgPicture.asset( AppAssets.salahTimeIcon, height: SizeConfig.getHeightMultiplier() * 0.4, ), ], Row( children: [ if (screenConfigVM.nextPrayerToShowEng.isNotEmpty) ...[ _buildPrayerColumn(screenConfigVM.globalConfigurationsModel.nextPrayerTextEng, "${screenConfigVM.nextPrayerToShowEng} "), ], if (screenConfigVM.nextPrayerToShowEng.isNotEmpty && screenConfigVM.nextPrayerToShowArb.isNotEmpty) ...[ Padding( padding: EdgeInsets.fromLTRB( SizeConfig.getWidthMultiplier()! * 0.1, SizeConfig.getHeightMultiplier()! * 0.18, SizeConfig.getWidthMultiplier()! * 0.1, 0, ), child: AppText("|", fontSize: SizeConfig.getWidthMultiplier()! * 1.8, color: AppColors.darkGreyTextColor), ), ], if (screenConfigVM.nextPrayerToShowArb.isNotEmpty) ...[ _buildPrayerColumn(screenConfigVM.globalConfigurationsModel.nextPrayerTextArb, screenConfigVM.nextPrayerToShowArb, isForArabic: true), ], ], ), SizedBox( width: SizeConfig.getWidthMultiplier() * 14, child: Center( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox(height: SizeConfig.getHeightMultiplier()! * 0.05), Padding( padding: EdgeInsets.only(left: SizeConfig.getWidthMultiplier()! * 0.5), child: AppText( _isMoreThanOneHour(_remainingTime) ? AppStrings.namazTimeText : AppStrings.timeRemainingText, fontSize: SizeConfig.getWidthMultiplier()! * 1.5, fontFamily: AppStrings.fontNamePoppins, ), ), _isMoreThanOneHour(_remainingTime) ? AppText( screenConfigVM.nextPrayerTime, fontSize: SizeConfig.getWidthMultiplier()! * 2.5, fontWeight: FontWeight.bold, color: AppColors.newRedColor, letterSpacing: 1.5, ) : AppText( _remainingTime, fontSize: SizeConfig.getWidthMultiplier()! * 2.5, fontWeight: FontWeight.bold, color: AppColors.newRedColor, letterSpacing: 1.5, ), ], ), ), ), ], ), ), ), ), ], if (screenConfigVM.globalConfigurationsModel.isWeatherReq && (screenConfigVM.globalConfigurationsModel.orientationTypeEnum != ScreenOrientationEnum.landscapeLeft && screenConfigVM.globalConfigurationsModel.orientationTypeEnum != ScreenOrientationEnum.landscapeRight)) ...[ SizedBox(width: SizeConfig.getWidthMultiplier()! * 1.7), Expanded( flex: isPortrait ? 3 : 4, child: customShadowSmoothContainer( height: SizeConfig.getHeightMultiplier() * 0.8, padding: EdgeInsets.symmetric( horizontal: isPortrait ? SizeConfig.getWidthMultiplier() * 3 : SizeConfig.getWidthMultiplier() * 1.5, vertical: SizeConfig.getHeightMultiplier() * 0.1, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ buildWeatherIcon(screenConfigVM.weathersWidgetModel.weatherIconPath ?? AppAssets.weatherIcon), SizedBox(width: SizeConfig.getWidthMultiplier() * 1.2), buildCurrentCityTemp("الرياض", "21 °C", true), SizedBox(width: SizeConfig.getWidthMultiplier() * 1.2), buildTempDetails(screenConfigVM.weathersWidgetModel.iconPhrase, screenConfigVM.weathersWidgetModel.maxTemp, screenConfigVM.weathersWidgetModel.minTemp, true), ], ), Row( children: [ buildCurrentCityTemp("Riyadh", "21 °C", false), SizedBox(width: SizeConfig.getWidthMultiplier() * 1.2), buildTempDetails(screenConfigVM.weathersWidgetModel.iconPhrase, screenConfigVM.weathersWidgetModel.maxTemp, screenConfigVM.weathersWidgetModel.minTemp, false), SizedBox(width: SizeConfig.getWidthMultiplier() * 1.2), buildWeatherIcon(screenConfigVM.weathersWidgetModel.weatherIconPath ?? AppAssets.weatherIcon), ], ), ], ), ), ), ], ], ), ), SizedBox(height: SizeConfig.getHeightMultiplier()! * 0.1), if (screenConfigVM.globalConfigurationsModel.isRssFeedReq && (screenConfigVM.rssFeedModel.rssFeed != null && screenConfigVM.rssFeedModel.rssFeed!.isNotEmpty)) ...[ // if (true)...[ customShadowSmoothContainer( removeRightBorder: true, height: SizeConfig.getHeightMultiplier()! * 0.3, width: double.infinity, child: Row( children: [ const HmgNewsWidget(tagTitle: "HMG News"), rssFeedWidget(), // customShadowSmoothContainer(child: rssFeedWidget()), ], ), ), ], ], ), ); }, ); } }