Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/mobile-v3/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:airqo/src/app/dashboard/bloc/dashboard/dashboard_bloc.dart';
import 'package:airqo/src/app/dashboard/bloc/forecast/forecast_bloc.dart';
import 'package:airqo/src/app/dashboard/repository/dashboard_repository.dart';
import 'package:airqo/src/app/dashboard/repository/forecast_repository.dart';
import 'package:airqo/src/app/dashboard/services/enhanced_location_service_manager.dart';
import 'package:airqo/src/app/learn/bloc/kya_bloc.dart';
import 'package:airqo/src/app/learn/repository/kya_repository.dart';
import 'package:airqo/src/app/map/bloc/map_bloc.dart';
Expand All @@ -27,17 +28,25 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:airqo/src/app/shared/pages/no_internet_banner.dart';
import 'package:airqo/src/app/shared/services/navigation_service.dart';
import 'package:loggy/loggy.dart';
import 'core/utils/app_loggy_setup.dart';
import 'package:airqo/src/app/other/language/bloc/language_bloc.dart';
import 'package:airqo/src/app/other/language/services/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';


final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> navigatorKey = NavigationService.navigatorKey;
void main() async {
WidgetsFlutterBinding.ensureInitialized();

try {
await EnhancedLocationServiceManager().initialize();
} catch (error, stackTrace) {
debugPrint('Location service initialization failed: $error');
debugPrint('Stack trace: $stackTrace');
}

await CacheManager().initialize();

const bool kReleaseMode = bool.fromEnvironment('dart.vm.product');
Expand Down
43 changes: 43 additions & 0 deletions src/mobile-v3/lib/src/app/dashboard/pages/dashboard_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'package:airqo/src/app/auth/pages/login_page.dart';
import 'package:airqo/src/app/dashboard/pages/location_selection/location_selection_screen.dart';
import 'package:airqo/src/app/dashboard/repository/country_repository.dart';
import 'package:airqo/src/app/dashboard/services/location_service_mananger.dart';
import 'package:airqo/src/app/surveys/services/survey_trigger_service.dart';
import 'package:airqo/src/app/surveys/repository/survey_repository.dart';
import 'package:airqo/src/meta/utils/colors.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
Expand Down Expand Up @@ -33,6 +36,10 @@ class _DashboardPageState extends State<DashboardPage> with UiLoggy {
String? userCountry;
// Background refresher that triggers silently
Timer? _backgroundRefreshTimer;

// Survey system services
final SurveyTriggerService _surveyTriggerService = SurveyTriggerService();
final LocationServiceManager _locationService = LocationServiceManager();

@override
void initState() {
Expand All @@ -56,11 +63,16 @@ class _DashboardPageState extends State<DashboardPage> with UiLoggy {
_backgroundRefreshTimer = Timer.periodic(Duration(minutes: 30), (_) {
_silentBackgroundRefresh();
});

// Initialize survey system
_initializeSurveySystem();
}

@override
void dispose() {
_backgroundRefreshTimer?.cancel();
_locationService.dispose();
_surveyTriggerService.dispose();
super.dispose();
}

Expand Down Expand Up @@ -328,4 +340,35 @@ class _DashboardPageState extends State<DashboardPage> with UiLoggy {
},
);
}

/// Initialize survey trigger system
Future<void> _initializeSurveySystem() async {
try {
// Set context for survey notifications
_surveyTriggerService.setContext(context);

// Initialize survey trigger service
await _surveyTriggerService.initialize();

// Load and set active surveys
final surveyRepository = SurveyRepository();
final surveys = await surveyRepository.getSurveys();
_surveyTriggerService.setActiveSurveys(surveys);

loggy.info('Survey system initialized with ${surveys.length} surveys');

// Start location tracking for research participants
// Only start if user has granted location permission during app initialization
final permissionResult = await _locationService.checkLocationPermission();
if (permissionResult.isSuccess) {
await _locationService.startLocationTracking();
loggy.info('Started location tracking for survey triggers');
} else {
loggy.info('Location permission not granted, survey triggers limited');
}

} catch (e) {
loggy.error('Error initializing survey system: $e');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:http/http.dart';
import 'package:loggy/loggy.dart';
import 'package:airqo/src/app/shared/services/cache_manager.dart';
import 'package:airqo/src/app/surveys/services/survey_trigger_service.dart';
import 'package:http/http.dart' as http;

abstract class DashboardRepository extends BaseRepository {
Expand Down Expand Up @@ -50,6 +51,9 @@ class DashboardImpl extends DashboardRepository with UiLoggy {

final _airQualityController = StreamController<AirQualityResponse>.broadcast();

// Survey trigger service for air quality-based surveys
final SurveyTriggerService _surveyTriggerService = SurveyTriggerService();

static const String _airQualityCacheKey = 'air_quality_readings';

@override
Expand Down Expand Up @@ -115,6 +119,9 @@ class DashboardImpl extends DashboardRepository with UiLoggy {

_airQualityController.add(dashboardResponse);

// Notify survey trigger service about air quality update
_notifySurveyTriggerService(dashboardResponse);

loggy.info('Successfully fetched and cached air quality data');
return dashboardResponse;
} else {
Expand Down Expand Up @@ -200,6 +207,32 @@ class DashboardImpl extends DashboardRepository with UiLoggy {
}
}

/// Helper method to notify survey trigger service about air quality updates
void _notifySurveyTriggerService(AirQualityResponse response) {
try {
// Extract relevant air quality data for survey triggers
if (response.measurements != null && response.measurements!.isNotEmpty) {
final measurement = response.measurements!.first; // Use first available measurement

final airQualityData = {
'pm2_5': measurement.pm25?.value,
'category': measurement.aqiCategory,
'timestamp': measurement.time,
'site_name': measurement.siteDetails?.name ?? measurement.siteDetails?.formattedName,
'location': {
'latitude': measurement.siteDetails?.approximateLatitude,
'longitude': measurement.siteDetails?.approximateLongitude,
}
};

_surveyTriggerService.updateAirQuality(airQualityData);
loggy.debug('Notified survey trigger service with air quality data: PM2.5=${measurement.pm25?.value}');
}
} catch (e) {
loggy.error('Error notifying survey trigger service: $e');
}
}

void dispose() {
_airQualityController.close();
_httpClient.close();
Expand Down
Loading