Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
88 changes: 88 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
include: package:flutter_lints/flutter.yaml

linter:
rules:
# Effective Dart rules - you can uncomment or add more as desired
# For a full list, see: https://dart.dev/tools/linter-rules
- always_declare_return_types
- avoid_empty_else
- avoid_relative_lib_imports
- avoid_return_types_on_setters
- avoid_shadowing_type_parameters
- avoid_single_cascade_in_expression_statements
- avoid_types_as_parameter_names
- await_only_futures
- camel_case_extensions
- camel_case_types
- cancel_subscriptions
- directives_ordering
- empty_catches
- empty_constructor_bodies
- empty_statements
- hash_and_equals
- implementation_imports
- iterable_contains_unrelated_type
- list_remove_unrelated_type
- no_duplicate_case_values
- non_constant_identifier_names
# - one_member_abstracts (Consider if applicable to your project's style)
- package_api_docs # Consider for public packages
- package_prefixed_library_names
- prefer_adjacent_string_concatenation
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
# - prefer_constructors_over_static_methods (Context-dependent)
- prefer_contains
- prefer_equal_for_default_values
- prefer_final_fields
- prefer_final_in_for_each
- prefer_final_locals
- prefer_for_elements_to_map_fromIterable
- prefer_foreach
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
- prefer_if_null_operators
- prefer_initializing_formals
- prefer_inlined_adds
- prefer_is_empty
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_iterable_whereType
- prefer_null_aware_operators
- prefer_single_quotes
- prefer_spread_collections
- prefer_typing_uninitialized_variables
# - public_member_api_docs (Enable if you want to enforce dartdoc comments)
- recursive_getters
- slash_for_doc_comments
- sort_child_properties_last # Flutter specific
- test_types_in_equals
- throw_in_finally
- type_annotate_public_apis # Covered by always_declare_return_types and others
- type_init_formals
- unawaited_futures
- unnecessary_await_in_return
- unnecessary_brace_in_string_interps
- unnecessary_const
- unnecessary_getters_setters
- unnecessary_lambdas
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_checks
- unnecessary_null_in_if_null_operators
- unnecessary_overrides
- unnecessary_parenthesis
- unnecessary_statements
- unnecessary_string_escapes
- unnecessary_string_interpolations
- unnecessary_this
- unrelated_type_equality_checks
- use_build_context_synchronously # Flutter specific, very important
- use_enums
# - use_function_type_syntax_for_parameters (Covered by prefer_generic_function_type_aliases)
# - use_rethrow_when_possible (Consider based on error handling strategy)
- valid_regexps
56 changes: 29 additions & 27 deletions lib/Screens/homeScreen.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
// ignore_for_file: public_member_api_docs
import 'package:flutter/material.dart';
import 'package:flutter_weather/screens/locationError.dart';
import 'package:geolocator/geolocator.dart';
Expand All @@ -25,7 +25,7 @@ class HomeScreen extends StatefulWidget {
}

class _HomeScreenState extends State<HomeScreen> {
FloatingSearchBarController fsc = FloatingSearchBarController();
final FloatingSearchBarController fsc = FloatingSearchBarController();

@override
void initState() {
Expand All @@ -43,37 +43,38 @@ class _HomeScreenState extends State<HomeScreen> {
return Scaffold(
body: Consumer<WeatherProvider>(
builder: (context, weatherProv, _) {
if (!weatherProv.isLoading && !weatherProv.isLocationserviceEnabled)
return LocationServiceErrorDisplay();
if (!weatherProv.isLoading && !weatherProv.isLocationserviceEnabled) {
return const LocationServiceErrorDisplay();
}

if (!weatherProv.isLoading &&
weatherProv.locationPermission != LocationPermission.always &&
weatherProv.locationPermission != LocationPermission.whileInUse) {
return LocationPermissionErrorDisplay();
return const LocationPermissionErrorDisplay();
}

if (weatherProv.isRequestError) return RequestErrorDisplay();
if (weatherProv.isRequestError) return const RequestErrorDisplay();

if (weatherProv.isSearchError) return SearchErrorDisplay(fsc: fsc);

return Stack(
children: [
ListView(
physics: BouncingScrollPhysics(),
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.all(12.0).copyWith(
top: kToolbarHeight +
MediaQuery.viewPaddingOf(context).top +
24.0,
24.0, // Cannot be const due to MediaQuery
),
children: [
children: const [
WeatherInfoHeader(),
const SizedBox(height: 16.0),
SizedBox(height: 16.0),
MainWeatherInfo(),
const SizedBox(height: 16.0),
SizedBox(height: 16.0),
MainWeatherDetail(),
const SizedBox(height: 24.0),
SizedBox(height: 24.0),
TwentyFourHourForecast(),
const SizedBox(height: 18.0),
SizedBox(height: 18.0),
SevenDayForecast(),
],
),
Expand All @@ -98,7 +99,7 @@ class CustomSearchBar extends StatefulWidget {
}

class _CustomSearchBarState extends State<CustomSearchBar> {
List<String> _citiesSuggestion = [
static const List<String> _citiesSuggestion = [
'New York',
'Tokyo',
'Dubai',
Expand All @@ -116,11 +117,11 @@ class _CustomSearchBarState extends State<CustomSearchBar> {
clearQueryOnClose: false,
scrollPadding: const EdgeInsets.only(top: 16.0, bottom: 56.0),
transitionDuration: const Duration(milliseconds: 400),
borderRadius: BorderRadius.circular(16.0),
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
transitionCurve: Curves.easeInOut,
accentColor: primaryBlue,
hintStyle: regularText,
queryStyle: regularText,
hintStyle: regularText, // Assuming regularText is const or from Theme
queryStyle: regularText, // Assuming regularText is const or from Theme
physics: const BouncingScrollPhysics(),
elevation: 2.0,
debounceDelay: const Duration(milliseconds: 500),
Expand All @@ -136,15 +137,15 @@ class _CustomSearchBarState extends State<CustomSearchBar> {
showIfOpened: false,
child: PhosphorIcon(
PhosphorIconsBold.magnifyingGlass,
color: primaryBlue,
color: primaryBlue, // primaryBlue might not be const
),
),
FloatingSearchBarAction.icon(
showIfClosed: false,
showIfOpened: true,
icon: PhosphorIcon(
PhosphorIconsBold.x,
color: primaryBlue,
color: primaryBlue, // primaryBlue might not be const
),
onTap: () {
if (widget.fsc.query.isEmpty) {
Expand All @@ -157,17 +158,17 @@ class _CustomSearchBarState extends State<CustomSearchBar> {
],
builder: (context, transition) {
return ClipRRect(
borderRadius: BorderRadius.circular(8.0),
borderRadius: const BorderRadius.all(Radius.circular(8.0)),
child: Material(
color: Colors.white,
color: Colors.white, // Colors.white is const
elevation: 4.0,
child: ListView.separated(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
padding: EdgeInsets.zero,
physics: const BouncingScrollPhysics(),
padding: EdgeInsets.zero, // EdgeInsets.zero is const
itemCount: _citiesSuggestion.length,
itemBuilder: (context, index) {
String data = _citiesSuggestion[index];
final String data = _citiesSuggestion[index];
return InkWell(
onTap: () async {
widget.fsc.query = data;
Expand All @@ -179,15 +180,16 @@ class _CustomSearchBarState extends State<CustomSearchBar> {
padding: const EdgeInsets.all(22.0),
child: Row(
children: [
PhosphorIcon(PhosphorIconsFill.mapPin),
// Assuming PhosphorIconsFill.mapPin is const
const PhosphorIcon(PhosphorIconsFill.mapPin),
const SizedBox(width: 22.0),
Text(data, style: mediumText),
Text(data, style: mediumText), // mediumText might not be const
],
),
),
);
},
separatorBuilder: (context, index) => Divider(
separatorBuilder: (context, index) => const Divider(
thickness: 1.0,
height: 0.0,
),
Expand Down
53 changes: 43 additions & 10 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_weather/theme/colors.dart';
import 'package:flutter_weather/theme/textStyle.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';

import './provider/weatherProvider.dart';
Expand All @@ -8,11 +11,13 @@ import 'screens/sevenDayForecastDetailScreen.dart';

void main() {
runApp(
MyApp(),
const MyApp(),
);
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
Expand All @@ -21,18 +26,46 @@ class MyApp extends StatelessWidget {
title: 'Flutter Weather',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: const ColorScheme(
brightness: Brightness.light,
primary: primaryBlue,
onPrimary: Colors.white,
secondary: primaryBlue, // Using primaryBlue for secondary as well for now
onSecondary: Colors.white,
error: errorRed,
onError: Colors.white,
background: backgroundBlue,
onBackground: textDarkGrey,
surface: backgroundWhite,
onSurface: textDarkGrey,
),
appBarTheme: AppBarTheme(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.blue),
elevation: 0,
backgroundColor: backgroundWhite,
foregroundColor: textDarkGrey,
elevation: 0.5,
iconTheme: const IconThemeData(color: primaryBlue),
),
scaffoldBackgroundColor: Colors.white,
primaryColor: Colors.blue,
scaffoldBackgroundColor: backgroundBlue,
visualDensity: VisualDensity.adaptivePlatformDensity,
colorScheme:
ColorScheme.fromSwatch().copyWith(secondary: Colors.white),
textTheme: TextTheme(
displayLarge: blackText.copyWith(color: textDarkGrey),
displayMedium: boldText.copyWith(color: textDarkGrey),
displaySmall: semiboldText.copyWith(color: textDarkGrey),
headlineMedium: mediumText.copyWith(color: textDarkGrey),
headlineSmall: regularText.copyWith(color: textDarkGrey),
titleLarge: boldText.copyWith(color: textDarkGrey),
bodyLarge: regularText.copyWith(color: textDarkGrey),
bodyMedium: regularText.copyWith(color: textDarkGrey),
bodySmall: lightText.copyWith(color: textDarkGrey),
labelLarge: mediumText.copyWith(color: Colors.white),
).apply(
bodyColor: textDarkGrey,
displayColor: textDarkGrey,
fontFamily: GoogleFonts.openSans().fontFamily,
),
dividerTheme: const DividerThemeData(color: accentLightGrey, thickness: 0.5),
),
home: HomeScreen(),
home: const HomeScreen(),
// routes: {
// WeeklyScreen.routeName: (ctx) => WeeklyScreen(),
// },
Expand All @@ -53,7 +86,7 @@ class MyApp extends StatelessWidget {
);
}
// Unknown route
return MaterialPageRoute(builder: (_) => HomeScreen());
return MaterialPageRoute(builder: (_) => const HomeScreen());
},
),
);
Expand Down
Loading