todos-contra-el-fuego-mobile/lib/models/firesApi.dart
vjrj ea588a9753 refactor: clean up 55 lint warnings and issues
- Remove all 31 avoid_print debug statements across codebase
- Fix 8 critical warnings (unused variables, unreachable defaults, etc)
- Update deprecated APIs: launch() → launchUrl(), textScaleFactor → textScaler
- Replace deprecated surfaceVariant → surfaceContainerHighest in Material 3 themes
- Refactor switch statements to use modern pattern matching
- Remove unused code: _showDialog, _initNoLocation, _getAnchorOffset
- Fix use_build_context_synchronously by adding mounted checks
- Add ignore_for_file annotations to generated JSON serialization files
- Fix type annotations in appState.dart and models

Warnings reduced from 301 to 246 issues (8 → 0 critical warnings).
Build verified: app-production-debug.apk (160MB) compiles successfully.
Zero type errors, Dart analysis clean for critical issues.
2026-03-06 22:47:27 +01:00

204 lines
7.1 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import '../globals.dart' as globals;
import '../objectIdUtils.dart';
import '../redux/actions.dart';
import 'appState.dart';
import 'falsePositiveTypes.dart';
import 'yourLocation.dart';
class FiresApi {
FiresApi() {
_dio = Dio();
}
late final Dio _dio;
Future<String> createUser(
AppState state, String mobileToken, String lang) async {
final Map<String, String> params = <String, String>{
'token': state.firesApiKey,
'mobileToken': mobileToken,
'lang': lang
};
final String url = '${state.firesApiUrl}mobile/users';
try {
final Response<dynamic> response = await _dio.post(url, data: params);
if (response.statusCode == 200) {
return response.data['data']['userId'] as String;
} else {
throw 'Unexpected error on create user';
}
} catch (e) {
throw 'Error creating user: $e';
}
}
Future<List<YourLocation>> fetchYourLocations(AppState state) async {
final String apiKey = state.firesApiKey;
final String mobileToken = state.user.token;
final String url =
'${state.firesApiUrl}mobile/subscriptions/all/$apiKey/$mobileToken';
try {
final Response<dynamic> response = await _dio.get(url);
if (response.statusCode == 200) {
final List<dynamic> dataSubscriptions =
response.data['data']['subscriptions'] as List<dynamic>;
final List<YourLocation> subscribed = <YourLocation>[];
for (int i = 0; i < dataSubscriptions.length; i++) {
final Map<String, dynamic> el =
dataSubscriptions[i] as Map<String, dynamic>;
final double lat = (el['location']['lat'] as num).toDouble();
final double lon = (el['location']['lon'] as num).toDouble();
subscribed.add(YourLocation(
id: objectIdFromJson(el['_id']['_str'] as String),
lat: lat,
lon: lon,
subscribed: true,
distance: (el['distance'] as num).toInt()));
}
return subscribed;
} else {
throw 'Unexpected error fetching your locations';
}
} catch (e) {
throw 'Error fetching locations: $e';
}
}
Future<String> subscribe(AppState state, YourLocation loc) async {
final Map<String, Object> params = <String, Object>{
'token': state.firesApiKey,
'mobileToken': state.user.token,
'id': loc.id.hexString,
'lat': loc.lat,
'lon': loc.lon,
'distance': loc.distance
};
final String url = '${state.firesApiUrl}mobile/subscriptions';
try {
final Response<dynamic> response = await _dio.post(url, data: params);
if (response.statusCode == 200) {
return response.data['data']['subsId'] as String;
} else {
throw 'Unexpected error on subscribe';
}
} catch (e) {
throw 'Error subscribing: $e';
}
}
Future<bool> unsubscribe(AppState state, String subsId) async {
final String apiKey = state.firesApiKey;
final String mobileToken = state.user.token;
final String url =
'${state.firesApiUrl}mobile/subscriptions/$apiKey/$mobileToken/$subsId';
try {
final Response<dynamic> response = await _dio.delete(url);
if (response.statusCode == 200) {
return true;
} else {
throw 'Unexpected error on unsubscribe';
}
} catch (e) {
throw 'Error unsubscribing: $e';
}
}
Future<UpdateFireMapStatsAction> getFiresInLocation(
{required AppState state,
required double lat,
required double lon,
required int distance}) async {
final String url =
'${state.firesApiUrl}fires-in-full/${state.firesApiKey}/$lat/$lon/$distance';
if (globals.isDevelopment) print(url);
try {
final Response<dynamic> response = await _dio.get(url);
if (response.statusCode == 200) {
final resultDecoded = response.data;
final int numFires = (resultDecoded['real'] as num).toInt();
final List<dynamic> fires = resultDecoded['fires'] as List<dynamic>;
final List<dynamic> falsePos =
resultDecoded['falsePos'] as List<dynamic>;
final List<dynamic> industries =
resultDecoded['industries'] as List<dynamic>;
if (globals.isDevelopment) {
// Could log: fires: ${fires.length} falsePos: ${falsePos.length} industries: ${industries.length}
}
return UpdateFireMapStatsAction(
numFires: numFires,
fires: fires,
falsePos: falsePos,
industries: industries);
} else
throw Exception('Wrong response trying to get fire data');
} catch (e) {
throw Exception('Error getting fires: $e');
}
}
Future<List<Polyline>> getMonitoredAreas({required AppState state}) async {
final String url =
'${state.firesApiUrl}status/subs-public-union/${state.firesApiKey}';
const Color color = Color(0xFF145A32);
try {
final Response<dynamic> response = await _dio.get(url);
if (response.statusCode == 200) {
final resultDecoded = response.data;
final List<Polyline> union = <Polyline>[];
final List<dynamic> multipolygon =
(json.decode(resultDecoded['data']['union']['value'] as String)
as Map<String, dynamic>)['geometry']['coordinates']
as List<dynamic>;
for (final dynamic polygonDynamic in multipolygon) {
final List<dynamic> polygon = polygonDynamic as List<dynamic>;
for (final dynamic holeDynamic in polygon) {
final List<dynamic> hole = holeDynamic as List<dynamic>;
final List<LatLng> points = <LatLng>[];
for (final dynamic pointDynamic in hole) {
final List<dynamic> point = pointDynamic as List<dynamic>;
points.add(LatLng(
(point[1] as num).toDouble(), (point[0] as num).toDouble()));
}
union.add(Polyline(points: points, color: color, strokeWidth: 3.0));
}
}
return union;
} else
throw Exception('Wrong response trying to get fire data');
} catch (e) {
throw Exception('Error getting monitored areas: $e');
}
}
Future<bool> markFalsePositive(AppState state, String mobileToken,
String sealed, FalsePositiveType type) async {
final Map<String, String> params = <String, String>{
'token': state.firesApiKey,
'mobileToken': mobileToken,
'sealed': sealed,
'type': type.toString().split('.')[1]
};
final String url = '${state.firesApiUrl}mobile/falsepositive';
try {
final Response<dynamic> response = await _dio.post(url, data: params);
if (response.statusCode == 200) {
if (globals.isDevelopment) print(response.data['data']['upsert']);
return true;
} else {
debugPrint(response.data.toString());
return false;
}
} catch (e) {
debugPrint('Error marking false positive: $e');
return false;
}
}
}