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.
This commit is contained in:
vjrj 2026-03-06 22:47:27 +01:00
parent 23838069c2
commit ea588a9753
25 changed files with 83 additions and 161 deletions

View file

@ -189,7 +189,6 @@ class _ActiveFiresPageState extends State<ActiveFiresPage> {
return StoreConnector<AppState, _ViewModel>(
distinct: true,
converter: (Store<AppState> store) {
print('New ViewModel of Active Fires');
return _ViewModel(
onAdd: (YourLocation loc) {
if (store.state.yourLocations.any(
@ -229,7 +228,6 @@ class _ActiveFiresPageState extends State<ActiveFiresPage> {
final String title = hasLocations
? S.of(context).firesInYourPlaces
: S.of(context).firesInTheWorld;
print('Building Active Fires');
return Scaffold(
key: _scaffoldKey,

View file

@ -25,7 +25,6 @@ class _CompassMapPluginWidgetState extends State<CompassMapPluginWidget> {
_mapController = MapController.of(context);
_initRotationMonitoring();
} catch (e) {
print('Error getting map controller: $e');
}
}
@ -61,7 +60,6 @@ class _CompassMapPluginWidgetState extends State<CompassMapPluginWidget> {
final MapController controller = MapController.of(context);
controller.rotate(0);
} catch (e) {
print('Error resetting rotation: $e');
}
}

View file

@ -128,7 +128,7 @@ class CustomStepper extends StatefulWidget {
this.onCustomStepTapped,
this.onCustomStepContinue,
this.onCustomStepCancel,
}) : assert(0 <= currentCustomStep && currentCustomStep < steps.length);
}) : assert(0 <= currentCustomStep && currentCustomStep < steps.length);
/// The steps of the stepper whose titles, subtitles, icons always get shown.
///
@ -322,14 +322,11 @@ class _CustomStepperState extends State<CustomStepper> {
}
Widget _buildVerticalControls() {
Color cancelColor;
// final Color cancelColor;
switch (Theme.of(context).brightness) {
case Brightness.light:
cancelColor = Colors.black54;
break;
case Brightness.dark:
cancelColor = Colors.white70;
break;
}
@ -341,9 +338,7 @@ class _CustomStepperState extends State<CustomStepper> {
margin: const EdgeInsets.only(top: 16.0),
child: ConstrainedBox(
constraints: const BoxConstraints.tightFor(height: 48.0),
child: const Row(
),
child: const Row(),
),
);
}

View file

@ -35,13 +35,10 @@ Future<String> getFileNameOfLang(
// https://github.com/flutter/flutter/issues/15325
Future<bool> assetNotExists(String asset) {
print('Does not exists $asset ?');
return rootBundle
.load(asset)
.then((_) => false)
.catchError((Object err, StackTrace stack) {
print(err);
print(stack);
return true;
});
}

View file

@ -29,8 +29,11 @@ class _FireAlertState extends State<FireAlert> {
child: FloatingActionButton(
heroTag: 'callAction',
child: const Icon(Icons.call),
onPressed: () {
launch('tel://112');
onPressed: () async {
final Uri url = Uri(scheme: 'tel', path: '112');
if (await canLaunchUrl(url)) {
await launchUrl(url);
}
},
),
);
@ -58,20 +61,16 @@ class _FireAlertState extends State<FireAlert> {
heroTag: 'tweetAction',
child: const Icon(CommunityMaterialIcons.twitter),
onPressed: () {
// In Android you can choose with app to use with setPackage but seems it's not implemented here
// https://stackoverflow.com/questions/6814268/android-share-on-facebook-twitter-mail-ecc
openPlacesDialog(_scaffoldKey).then((YourLocation yourLocation) {
final String where =
yourLocation.description.replaceAll(' ', '').split(',')[0];
print(where);
Share.shareWithResult(S
.of(context)
.tweetAboutSelf(yourLocation.description, '#IF$where'));
}).catchError((onError) {
final BuildContext? ctx = _scaffoldKey.currentContext;
if (ctx != null) {
ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
content: Text(S.of(ctx).errorFirePlaceDialog)));
}).catchError((Object onError) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(S.of(context).errorFirePlaceDialog)));
}
});
},

View file

@ -11,10 +11,6 @@ Marker FireMarker(
FireMarkType type, [
VoidCallback? onTap,
]) {
// Calculate offset based on marker type
// Anchor point for center of marker: (40, calculated_y)
final Offset offset = _getAnchorOffset(type);
return Marker(
point: pos,
width: 80.0,
@ -26,21 +22,3 @@ Marker FireMarker(
),
);
}
/// Get the anchor offset based on marker type
Offset _getAnchorOffset(FireMarkType type) {
switch (type) {
case FireMarkType.position:
return const Offset(40.0, 20.0);
case FireMarkType.fire:
return const Offset(40.0, 24.0);
case FireMarkType.pixel:
// Auto-calculate based on marker size
return const Offset(40.0, 40.0);
case FireMarkType.falsePos:
case FireMarkType.industry:
return const Offset(40.0, 35.0);
default:
return const Offset(40.0, 40.0);
}
}

View file

@ -4,24 +4,19 @@ import 'colors.dart';
import 'fireMarkType.dart';
class FireMarkerIcon extends StatelessWidget {
const FireMarkerIcon(this.type, {super.key});
final FireMarkType type;
@override
Widget build(BuildContext context) {
switch (type) {
case FireMarkType.position:
return const Icon(Icons.location_on, color: fires600, size: 50.0);
case FireMarkType.pixel:
return const Icon(Icons.brightness_1, color: fires900, size: 3.0);
case FireMarkType.fire:
return Image.asset('images/fire-marker-l.png');
case FireMarkType.industry:
return Image.asset('images/industry-marker-reg.png');
case FireMarkType.falsePos:
default:
return Image.asset('images/industry-marker.png');
}
return switch (type) {
FireMarkType.position =>
const Icon(Icons.location_on, color: fires600, size: 50.0),
FireMarkType.pixel =>
const Icon(Icons.brightness_1, color: fires900, size: 3.0),
FireMarkType.fire => Image.asset('images/fire-marker-l.png'),
FireMarkType.industry => Image.asset('images/industry-marker-reg.png'),
FireMarkType.falsePos => Image.asset('images/industry-marker.png'),
};
}
}

View file

@ -150,8 +150,6 @@ class _FireNotificationListState extends State<FireNotificationList> {
return StoreConnector<AppState, _ViewModel>(
distinct: true,
converter: (Store<AppState> store) {
print(
'New ViewModel of Fires Notifications (unread: ${store.state.fireNotificationsUnread})');
return _ViewModel(
isLoaded: store.state.isLoaded,
onDeleteAll: () {
@ -183,7 +181,6 @@ class _FireNotificationListState extends State<FireNotificationList> {
builder: (BuildContext context, _ViewModel view) {
final bool hasFireNotifications = view.fireNotifications.isNotEmpty;
final String title = S.of(context).fireNotificationsTitle;
print('Building Fire Notifications List');
return Scaffold(
key: _scaffoldKey,
@ -221,7 +218,8 @@ class _FireNotificationListState extends State<FireNotificationList> {
.of(context)
.fireNotificationsDescription,
textAlign: TextAlign.center,
textScaleFactor: 1.1,
textScaler:
const TextScaler.linear(1.1),
style: const TextStyle(
height: 1.3, color: Colors.black45))
]))))
@ -240,7 +238,7 @@ class _FireNotificationListState extends State<FireNotificationList> {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (BuildContext context) => genericMap()));
builder: (BuildContext context) => const genericMap()));
}
Future<void> _showConfirmDialog(_ViewModel view) {

View file

@ -71,7 +71,6 @@ class _FiresAppState extends State<FiresApp> {
S.delegate.resolution(fallback: const Locale('en', '')),
home: home,
onGenerateTitle: (BuildContext context) {
print('MaterialApp onGenerateTitle');
return S.of(context).appName;
},
theme: isDevelopment ? devFiresTheme : firesTheme,

View file

@ -31,7 +31,6 @@ import 'zoomMapPlugin.dart';
@immutable
class _ViewModel {
const _ViewModel(
{required this.mapState,
required this.serverUrl,
@ -96,7 +95,6 @@ class _genericMapState extends State<genericMap> {
_initialLocation = _location?.copyWith();
},
converter: (Store<AppState> store) {
print('New map viewer');
return _ViewModel(
onSubs: (YourLocation loc) {
store.dispatch(SubscribeAction());
@ -112,7 +110,8 @@ class _genericMapState extends State<genericMap> {
onSlide: (YourLocation loc) {
store.dispatch(UpdateYourLocationMapAction(loc));
},
onEdit: (YourLocation loc) => store.dispatch(EditYourLocationAction(loc)),
onEdit: (YourLocation loc) =>
store.dispatch(EditYourLocationAction(loc)),
onEditing: (YourLocation loc) {
store.dispatch(UpdateYourLocationMapAction(loc));
},
@ -123,8 +122,9 @@ class _genericMapState extends State<genericMap> {
store.dispatch(UpdateYourLocationMapAction(loc));
store.dispatch(EditConfirmYourLocationAction(loc));
},
onFalsePositive: (FireNotification notif, FalsePositiveType type) => store
.dispatch(MarkFireAsFalsePositiveAction(notif, type)),
onFalsePositive: (FireNotification notif,
FalsePositiveType type) =>
store.dispatch(MarkFireAsFalsePositiveAction(notif, type)),
onFirePressed: (LatLng latLng, DateTime when, String type) {
_showFireDialog(latLng, when, type);
},
@ -136,18 +136,15 @@ class _genericMapState extends State<genericMap> {
builder: (BuildContext context, _ViewModel view) {
final YourLocation? location = view.mapState.yourLocation;
_location = location?.copyWith();
print('New map builder with ${_location?.description}');
final FireMapState mapState = view.mapState;
final FireMapStatus status = mapState.status;
final FireMapLayer layer = mapState.layer;
print('Build map with status: $status and layer $layer');
const double maxZoom = 18.0; // works?
final MapOptions mapOptions = MapOptions(
initialCenter:
LatLng(_location?.lat ?? 0.0, _location?.lon ?? 0.0),
initialCenter: LatLng(_location?.lat ?? 0.0, _location?.lon ?? 0.0),
maxZoom: maxZoom,
onTap: (TapPosition tapPosition, LatLng latLng) {
if (status == FireMapStatus.edit && _location != null) {
@ -221,11 +218,11 @@ class _genericMapState extends State<genericMap> {
urlTemplate: baseLayer,
subdomains: subdomains,
userAgentPackageName: 'com.example.fires_flutter',
additionalOptions: const <String, String> {
// 'opacity': '0.1',
},
),
if (globals.isDevelopment) const ZoomMapPluginWidget() else const DummyMapPluginWidget(),
if (globals.isDevelopment)
const ZoomMapPluginWidget()
else
const DummyMapPluginWidget(),
const CompassMapPluginWidget(),
MarkerLayer(
markers: buildMarkers(
@ -316,8 +313,9 @@ class _genericMapState extends State<genericMap> {
onSave: () => view.onEditConfirm(_location!),
onCancel: () =>
view.onEditCancel(_initialLocation ?? _location!),
onFalsePositive: (FireNotification sealed, FalsePositiveType type) =>
view.onFalsePositive(sealed, type),
onFalsePositive:
(FireNotification sealed, FalsePositiveType type) =>
view.onFalsePositive(sealed, type),
state: view.mapState,
scaffoldKey: _scaffoldKey,
),
@ -347,8 +345,7 @@ class _genericMapState extends State<genericMap> {
? <Widget>[
FireDistanceSlider(
initialValue:
_location?.distance ?? 0
,
_location?.distance ?? 0,
onSlide: (int distance) {
if (_location != null) {
_location!.distance = distance;
@ -400,12 +397,12 @@ class _genericMapState extends State<genericMap> {
bool isNotif,
OnFirePressedInMap onFirePressed) {
final List<Marker> markers = <Marker>[];
print(
'building markers: fires: ${fires.length} falsePos: ${falsePosList.length} industries: ${industries.length}, isNotif: $isNotif ');
// Debug: building markers: fires: ${fires.length} falsePos: ${falsePosList.length} industries: ${industries.length}, isNotif: $isNotif
// const calibrate = false; // useful when we change the fire icons size
for (final falsePos in falsePosList) {
for (final falsePos in falsePosList) {
try {
final List<dynamic> coords = falsePos['geo']['coordinates'] as List<dynamic>;
final List<dynamic> coords =
falsePos['geo']['coordinates'] as List<dynamic>;
// print('false pos: ${coords}');
final LatLng loc = LatLng(
(coords[1] as num).toDouble(), (coords[0] as num).toDouble());
@ -414,14 +411,14 @@ class _genericMapState extends State<genericMap> {
}));
// if (calibrate) markers.add(FireMarker(loc, FireMarkType.pixel));
} catch (e, stackTrace) {
print('Failed to process $falsePos');
reportError(e, stackTrace);
}
}
for (final industry in industries) {
for (final industry in industries) {
try {
// print(fire['geo']['coordinates']);
final List<dynamic> coords = industry['geo']['coordinates'] as List<dynamic>;
final List<dynamic> coords =
industry['geo']['coordinates'] as List<dynamic>;
final LatLng loc = LatLng(
(coords[1] as num).toDouble(), (coords[0] as num).toDouble());
markers.add(FireMarker(loc, FireMarkType.industry, () {
@ -429,22 +426,19 @@ class _genericMapState extends State<genericMap> {
}));
// if (calibrate) markers.add(FireMarker(loc, FireMarkType.pixel));
} catch (e, stackTrace) {
print('Failed to process $industry');
reportError(e, stackTrace);
}
}
for (final fire in fires) {
for (final fire in fires) {
try {
final LatLng loc = LatLng(
(fire['lat'] as num).toDouble(), (fire['lon'] as num).toDouble());
markers.add(FireMarker(loc, FireMarkType.fire, () {
onFirePressed(loc, DateTime.parse(fire['when'].toString()),
fire['type'] as String);
print('fire $fire pressed');
}));
markers.add(FireMarker(loc, FireMarkType.pixel));
} catch (e, stackTrace) {
print('Failed to process $fire');
reportError(e, stackTrace);
}
}

View file

@ -38,13 +38,9 @@ class _GlobalFiresBottomStatsState extends State<GlobalFiresBottomStats> {
activeFires = count;
});
} catch (e) {
print('Cannot get the last fire stats');
print(e);
}
});
} catch (e) {
print('Cannot get the last fire check');
print(e);
}
});
}

View file

@ -207,24 +207,6 @@ class _HomePageState extends State<HomePage> {
});
}
void _showDialog(String message) {
final BuildContext? context = _scaffoldKey.currentContext;
if (context == null) return;
showDialog<bool>(
context: context,
builder: (_) => AlertDialog(
content: Text(message),
actions: <Widget>[
TextButton(
child: Text(S.of(context).CLOSE),
onPressed: () {
Navigator.pop(context);
},
),
],
));
}
void _showItemDialog(Map<String, dynamic> message, FireNotification notif) {
final BuildContext? context = _scaffoldKey.currentContext;
if (context == null) return;
@ -236,7 +218,6 @@ class _HomePageState extends State<HomePage> {
_navigateToItemDetail(message);
}
}).catchError((Object e) {
print('$e');
});
}

View file

@ -30,7 +30,6 @@ Future<YourLocation> getUserLocation(
await getReverseLocation(lat: yl.lat, lon: yl.lon, external: true);
yl.description = address;
} catch (e) {
print('We cannot reverse geolocate');
}
}
return yl;
@ -59,13 +58,11 @@ Future<String> getReverseLocation(
final geo.Placemark first = placemarks.first;
final String address =
'${first.street}, ${first.locality}, ${first.administrativeArea}, ${first.country}';
print('${first.name} : $address');
return address;
} else {
return 'Unable to determine address';
}
} catch (e) {
print('Error in reverse geocoding: $e');
throw Exception('Failed to reverse geocode: $e');
}
}

View file

@ -38,7 +38,6 @@ Future<void> mainCommon(List<Middleware<AppState>> otherMiddleware) async {
getIt.registerSingleton<FiresApi>(FiresApi());
loadPackageInfo().then((PackageInfo packageInfo) {
globals.appVersion = packageInfo.version;
print('Running version ${packageInfo.version}');
loadSecrets().then((Map<String, dynamic> secrets) {
final Store<AppState> store = Store<AppState>(appStateReducer,
initialState: AppState(

View file

@ -8,8 +8,11 @@ import 'globals.dart' as globals;
import 'mainDrawer.dart';
abstract class MarkdownPage extends StatefulWidget {
const MarkdownPage({super.key, required this.title, required this.route, required this.file});
const MarkdownPage(
{super.key,
required this.title,
required this.route,
required this.file});
final String title;
final Future<String> file;
final String route;
@ -20,7 +23,6 @@ abstract class MarkdownPage extends StatefulWidget {
}
class _MarkdownPageState extends State<MarkdownPage> {
_MarkdownPageState(
{required this.title, required this.file, required this.route});
final String title;
@ -40,7 +42,7 @@ class _MarkdownPageState extends State<MarkdownPage> {
});
});
return Scaffold(
appBar: AppBar(title: Text(title ?? '')),
appBar: AppBar(title: Text(title)),
drawer: MainDrawer(context, route),
body: Markdown(data: pageData));
}

View file

@ -19,7 +19,6 @@ part 'appState.g.dart';
@immutable
@JsonSerializable(nullable: false)
class AppState {
const AppState(
{this.yourLocations = const <YourLocation>[],
this.fireNotifications = const <FireNotification>[],
@ -35,10 +34,8 @@ class AppState {
this.monitoredAreas = const <Polyline>[],
this.fireMapState = const FireMapState.initial()});
@JsonKey(ignore: true)
factory AppState.fromJson(Map<String, dynamic> json) =>
_$AppStateFromJson(json);
@JsonKey(ignore: true)
final bool isLoading;
@JsonKey(ignore: true)
final bool isLoaded;
@ -102,7 +99,8 @@ class AppState {
typedef AddYourLocationFunction = void Function(YourLocation loc);
typedef DeleteYourLocationFunction = void Function(YourLocation loc);
typedef OnRefreshYourLocationsFunction = void Function(Completer<void> callback);
typedef OnRefreshYourLocationsFunction = void Function(
Completer<void> callback);
typedef ToggleSubscriptionFunction = void Function(YourLocation loc);
typedef OnLocationTapFunction = void Function(YourLocation loc);
typedef OnSubscribeFunction = void Function(YourLocation loc);
@ -114,7 +112,8 @@ typedef OnLocationEditing = void Function(YourLocation loc);
typedef OnLocationEditConfirm = void Function(YourLocation loc);
typedef OnLocationEditCancel = void Function(YourLocation loc);
typedef TapFireNotificationFunction = void Function(FireNotification notif);
typedef OnFirePressedInMap = void Function(LatLng latLng, DateTime when, String source);
typedef OnFirePressedInMap = void Function(
LatLng latLng, DateTime when, String source);
// typedef void OnReceivedFireNotificationFunction(FireNotification notif);
typedef DeleteFireNotificationFunction = void Function(FireNotification notif);
typedef DeleteAllFireNotificationFunction = void Function();

View file

@ -27,12 +27,14 @@ AppState _$AppStateFromJson(Map json) => $checkedCreate(
Map<String, dynamic>.from(e as Map)))
.toList() ??
const <FireNotification>[]),
isLoading: $checkedConvert('isLoading', (v) => v as bool? ?? false),
);
return val;
},
);
Map<String, dynamic> _$AppStateToJson(AppState instance) => <String, dynamic>{
'isLoading': instance.isLoading,
'yourLocations': instance.yourLocations.map((e) => e.toJson()).toList(),
'fireNotifications':
instance.fireNotifications.map((e) => e.toJson()).toList(),

View file

@ -6,7 +6,7 @@ part of 'fireNotification.dart';
// JsonSerializableGenerator
// **************************************************************************
FireNotification _$FireNotificationFromJson(Map<dynamic,dynamic> json) => $checkedCreate(
FireNotification _$FireNotificationFromJson(Map json) => $checkedCreate(
'FireNotification',
json,
($checkedConvert) {

View file

@ -14,7 +14,6 @@ import 'falsePositiveTypes.dart';
import 'yourLocation.dart';
class FiresApi {
FiresApi() {
_dio = Dio();
}
@ -52,7 +51,8 @@ class FiresApi {
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 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(
@ -86,7 +86,6 @@ class FiresApi {
if (response.statusCode == 200) {
return response.data['data']['subsId'] as String;
} else {
print(response.data);
throw 'Unexpected error on subscribe';
}
} catch (e) {
@ -125,15 +124,13 @@ class FiresApi {
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>;
final List<dynamic> falsePos =
resultDecoded['falsePos'] as List<dynamic>;
final List<dynamic> industries =
resultDecoded['industries'] as List<dynamic>;
if (globals.isDevelopment) {
final int firesCount = fires.length;
final int industriesCount = industries.length;
final int falsePosCount = falsePos.length;
print(
'(Pos: $lat, $lon) real: $numFires, fire: $firesCount falsePos: $falsePosCount industries: $industriesCount');
// Could log: fires: ${fires.length} falsePos: ${falsePos.length} industries: ${industries.length}
}
return UpdateFireMapStatsAction(
numFires: numFires,

View file

@ -7,7 +7,6 @@ part 'yourLocation.g.dart';
@JsonSerializable(nullable: false)
class YourLocation {
YourLocation(
{required this.id,
required this.lat,
@ -33,10 +32,6 @@ class YourLocation {
static late final YourLocation noLocation;
static const int? withoutStats = null;
static void _initNoLocation() {
noLocation = YourLocation(
id: ObjectId(), lat: 0.0, lon: 0.0);
}
Map<String, dynamic> toJson() => _$YourLocationToJson(this);
YourLocation copyWith(

View file

@ -156,12 +156,10 @@ void fetchDataMiddleware(
.then((List<YourLocation> subscribedLocations) {
// If it succeeds, dispatch a success action with the YourLocations.
// Our reducer will then update the State using these YourLocations.
print('Subscribed to: ${subscribedLocations.length}');
// unsubscribe all locally to sync the subs state
for (final YourLocation location in localLocations) {
location.subscribed = false;
}
print('Local persisted: ${localLocations.length}');
for (final YourLocation subsLoc in subscribedLocations) {
final YourLocation locSubs = localLocations.firstWhere(
(YourLocation localLocation) => localLocation.id == subsLoc.id,

View file

@ -9,10 +9,8 @@ bool useSentry = !globals.isDevelopment;
Future<void> reportError(dynamic error, dynamic stackTrace) async {
// Print the exception to the console
print('Caught error: $error');
if (!useSentry) {
// Print the full stacktrace in debug mode
print(stackTrace);
return;
} else {
// Send the Exception and Stacktrace to Sentry in Production mode

View file

@ -25,8 +25,11 @@ class _SupportPageState extends State<SupportPage> {
child: OutlinedButton.icon(
icon: const Icon(Icons.favorite_border),
label: Text(S.of(context).comunesSupportBtn),
onPressed: () {
launch('https://comunes.org/');
onPressed: () async {
final Uri url = Uri.parse('https://comunes.org/');
if (await canLaunchUrl(url)) {
await launchUrl(url);
}
},
),
);
@ -65,9 +68,12 @@ class _SupportPageState extends State<SupportPage> {
child: OutlinedButton.icon(
icon: const Icon(Icons.translate),
label: Text(S.of(context).translateBtn),
onPressed: () {
launch(
onPressed: () async {
final Uri url = Uri.parse(
'https://translate.comunes.org/projects/todos-contra-el-fuego/');
if (await canLaunchUrl(url)) {
await launchUrl(url);
}
},
),
);
@ -77,8 +83,7 @@ class _SupportPageState extends State<SupportPage> {
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar:
AppBar(title: Text(S.of(context).supportThisInitiative)),
appBar: AppBar(title: Text(S.of(context).supportThisInitiative)),
drawer: MainDrawer(context, SupportPage.routeName),
body: Padding(
padding: const EdgeInsets.all(8.0),

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'colors.dart';
// ignore_for_file: avoid_redundant_argument_values
final ThemeData firesTheme = _buildFiresTheme();
ThemeData _buildFiresTheme() {
@ -25,7 +26,7 @@ ThemeData _buildFiresTheme() {
onErrorContainer: m3OnErrorContainer,
surface: m3Surface,
onSurface: m3OnSurface,
surfaceVariant: m3SurfaceVariant,
surfaceContainerHighest: m3SurfaceVariant,
onSurfaceVariant: m3OnSurfaceVariant,
outline: m3Outline,
outlineVariant: m3OutlineVariant,
@ -168,7 +169,7 @@ ThemeData _buildFiresTheme() {
// ========================================================================
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: colorScheme.surfaceVariant.withValues(alpha: 0.5),
fillColor: colorScheme.surfaceContainerHighest.withValues(alpha: 0.5),
isDense: false,
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'colors.dart';
// ignore_for_file: avoid_redundant_argument_values
final ThemeData devFiresTheme = _buildFiresTheme();
ThemeData _buildFiresTheme() {
@ -26,7 +27,7 @@ ThemeData _buildFiresTheme() {
onErrorContainer: m3OnErrorContainer,
surface: m3Surface,
onSurface: m3OnSurface,
surfaceVariant: m3SurfaceVariant,
surfaceContainerHighest: m3SurfaceVariant,
onSurfaceVariant: m3OnSurfaceVariant,
outline: m3Outline,
outlineVariant: m3OutlineVariant,
@ -169,7 +170,7 @@ ThemeData _buildFiresTheme() {
// ========================================================================
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: colorScheme.surfaceVariant.withValues(alpha: 0.5),
fillColor: colorScheme.surfaceContainerHighest.withValues(alpha: 0.5),
isDense: false,
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),