diff --git a/README.md b/README.md index 9152445..b3bb0fb 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,24 @@ -# Flutter Course Code +# weather_application -## Getting Started +Icon app
+ +
-This project is a starting point for a Flutter application. +Splash screen
+ +
-A few resources to get you started if this is your first Flutter project: +Main page
+ +
-- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) +Select City Page
+ +
-For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +After Select City
+ +
+No internet connection
+ +
diff --git a/android/app/build.gradle b/android/app/build.gradle index 617083c..8b3a533 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -43,7 +43,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.contacts_01" + applicationId "com.example.weather_application" minSdkVersion 16 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index 47d7ea9..813bc1f 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.example.weather_application"> diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 609e8ad..9472cc3 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,8 +1,8 @@ + package="com.example.weather_application"> + android:label="weather_application" + android:icon="@mipmap/launcher_icon"> + package="com.example.weather_application"> diff --git a/assets/cities_all.csv b/assets/cities_all.csv new file mode 100644 index 0000000..eb485c9 --- /dev/null +++ b/assets/cities_all.csv @@ -0,0 +1,68 @@ +Zaxo +Umm Qaşr +Tozkhurmato +Tikrīt +Tallkayf +Sīnah +Sāmarrā’ +Nāḩīyat Saddat al Hindīyah +Ruwāndiz +Al-Hamdaniya +Mandalī +Koysinceq +Kifrī +Kirkuk +Karbala +Erbil +Hīt +Ḩalabjah +Ḩadīthah +Dihok +Jamjamāl +Bayjī +Baqubah +Baynjiwayn +Balad +Baghdad +Az Zubayr +Aş Şuwayrah +As Sulaymānīyah +As Samawah +Nāḩiyat ash Shināfīyah +Ash Shaţrah +Ash Shāmīyah +Ar Ruţbah +Ar Rumaythah +Ramadi +‘Aqrah +An Nāşirīyah +Najaf +‘Anat al Qadīmah +Imam Qasim +Al Musayyib +Al Mishkhāb +Al Miqdādīyah +Al Mawşil al Jadīdah +Mosul +Al Kūt +Kufa +Khāliş +‘Alī al Gharbī +Al Hindīyah +Al Ḩillah +Al Ḩayy +Al Hārithah +Nahiyat Ghammas +Nāḩiyat al Fuhūd +Al Fāw +Al Fallūjah +Basrah +Al ‘Azīzīyah +Al ‘Amārah +‘Afak +Ad Dujayl +Ad Dīwānīyah +Abū Ghurayb +Al Başrah al Qadīmah +Sinjār +‘Anah \ No newline at end of file diff --git a/assets/icon_app.png b/assets/icon_app.png new file mode 100644 index 0000000..2c20912 Binary files /dev/null and b/assets/icon_app.png differ diff --git a/assets/icons/a01d.png b/assets/icons/a01d.png new file mode 100644 index 0000000..227d0aa Binary files /dev/null and b/assets/icons/a01d.png differ diff --git a/assets/icons/a01n.png b/assets/icons/a01n.png new file mode 100644 index 0000000..b66582a Binary files /dev/null and b/assets/icons/a01n.png differ diff --git a/assets/icons/a02d.png b/assets/icons/a02d.png new file mode 100644 index 0000000..227d0aa Binary files /dev/null and b/assets/icons/a02d.png differ diff --git a/assets/icons/a02n.png b/assets/icons/a02n.png new file mode 100644 index 0000000..b66582a Binary files /dev/null and b/assets/icons/a02n.png differ diff --git a/assets/icons/a03d.png b/assets/icons/a03d.png new file mode 100644 index 0000000..227d0aa Binary files /dev/null and b/assets/icons/a03d.png differ diff --git a/assets/icons/a03n.png b/assets/icons/a03n.png new file mode 100644 index 0000000..b66582a Binary files /dev/null and b/assets/icons/a03n.png differ diff --git a/assets/icons/a04d.png b/assets/icons/a04d.png new file mode 100644 index 0000000..227d0aa Binary files /dev/null and b/assets/icons/a04d.png differ diff --git a/assets/icons/a04n.png b/assets/icons/a04n.png new file mode 100644 index 0000000..b66582a Binary files /dev/null and b/assets/icons/a04n.png differ diff --git a/assets/icons/a05d.png b/assets/icons/a05d.png new file mode 100644 index 0000000..227d0aa Binary files /dev/null and b/assets/icons/a05d.png differ diff --git a/assets/icons/a05n.png b/assets/icons/a05n.png new file mode 100644 index 0000000..b66582a Binary files /dev/null and b/assets/icons/a05n.png differ diff --git a/assets/icons/a06d.png b/assets/icons/a06d.png new file mode 100644 index 0000000..227d0aa Binary files /dev/null and b/assets/icons/a06d.png differ diff --git a/assets/icons/a06n.png b/assets/icons/a06n.png new file mode 100644 index 0000000..b66582a Binary files /dev/null and b/assets/icons/a06n.png differ diff --git a/assets/icons/c01d.png b/assets/icons/c01d.png new file mode 100644 index 0000000..e1576b1 Binary files /dev/null and b/assets/icons/c01d.png differ diff --git a/assets/icons/c01n.png b/assets/icons/c01n.png new file mode 100644 index 0000000..abe8220 Binary files /dev/null and b/assets/icons/c01n.png differ diff --git a/assets/icons/c02d.png b/assets/icons/c02d.png new file mode 100644 index 0000000..078706b Binary files /dev/null and b/assets/icons/c02d.png differ diff --git a/assets/icons/c02n.png b/assets/icons/c02n.png new file mode 100644 index 0000000..2f0073b Binary files /dev/null and b/assets/icons/c02n.png differ diff --git a/assets/icons/c03d.png b/assets/icons/c03d.png new file mode 100644 index 0000000..26745cf Binary files /dev/null and b/assets/icons/c03d.png differ diff --git a/assets/icons/c03n.png b/assets/icons/c03n.png new file mode 100644 index 0000000..bb69f93 Binary files /dev/null and b/assets/icons/c03n.png differ diff --git a/assets/icons/c04d.png b/assets/icons/c04d.png new file mode 100644 index 0000000..2403967 Binary files /dev/null and b/assets/icons/c04d.png differ diff --git a/assets/icons/c04n.png b/assets/icons/c04n.png new file mode 100644 index 0000000..2403967 Binary files /dev/null and b/assets/icons/c04n.png differ diff --git a/assets/icons/d01d.png b/assets/icons/d01d.png new file mode 100644 index 0000000..f36a066 Binary files /dev/null and b/assets/icons/d01d.png differ diff --git a/assets/icons/d01n.png b/assets/icons/d01n.png new file mode 100644 index 0000000..f36a066 Binary files /dev/null and b/assets/icons/d01n.png differ diff --git a/assets/icons/d02d.png b/assets/icons/d02d.png new file mode 100644 index 0000000..f36a066 Binary files /dev/null and b/assets/icons/d02d.png differ diff --git a/assets/icons/d02n.png b/assets/icons/d02n.png new file mode 100644 index 0000000..f36a066 Binary files /dev/null and b/assets/icons/d02n.png differ diff --git a/assets/icons/d03d.png b/assets/icons/d03d.png new file mode 100644 index 0000000..f36a066 Binary files /dev/null and b/assets/icons/d03d.png differ diff --git a/assets/icons/d03n.png b/assets/icons/d03n.png new file mode 100644 index 0000000..f36a066 Binary files /dev/null and b/assets/icons/d03n.png differ diff --git a/assets/icons/f01d.png b/assets/icons/f01d.png new file mode 100644 index 0000000..c9a0f84 Binary files /dev/null and b/assets/icons/f01d.png differ diff --git a/assets/icons/f01n.png b/assets/icons/f01n.png new file mode 100644 index 0000000..c9a0f84 Binary files /dev/null and b/assets/icons/f01n.png differ diff --git a/assets/icons/r01d.png b/assets/icons/r01d.png new file mode 100644 index 0000000..c9a0f84 Binary files /dev/null and b/assets/icons/r01d.png differ diff --git a/assets/icons/r01n.png b/assets/icons/r01n.png new file mode 100644 index 0000000..c9a0f84 Binary files /dev/null and b/assets/icons/r01n.png differ diff --git a/assets/icons/r02d.png b/assets/icons/r02d.png new file mode 100644 index 0000000..c9a0f84 Binary files /dev/null and b/assets/icons/r02d.png differ diff --git a/assets/icons/r02n.png b/assets/icons/r02n.png new file mode 100644 index 0000000..c9a0f84 Binary files /dev/null and b/assets/icons/r02n.png differ diff --git a/assets/icons/r03d.png b/assets/icons/r03d.png new file mode 100644 index 0000000..0183e5b Binary files /dev/null and b/assets/icons/r03d.png differ diff --git a/assets/icons/r03n.png b/assets/icons/r03n.png new file mode 100644 index 0000000..0183e5b Binary files /dev/null and b/assets/icons/r03n.png differ diff --git a/assets/icons/r04d.png b/assets/icons/r04d.png new file mode 100644 index 0000000..c9a0f84 Binary files /dev/null and b/assets/icons/r04d.png differ diff --git a/assets/icons/r04n.png b/assets/icons/r04n.png new file mode 100644 index 0000000..d53c701 Binary files /dev/null and b/assets/icons/r04n.png differ diff --git a/assets/icons/r05d.png b/assets/icons/r05d.png new file mode 100644 index 0000000..850ae3a Binary files /dev/null and b/assets/icons/r05d.png differ diff --git a/assets/icons/r05n.png b/assets/icons/r05n.png new file mode 100644 index 0000000..d53c701 Binary files /dev/null and b/assets/icons/r05n.png differ diff --git a/assets/icons/r06d.png b/assets/icons/r06d.png new file mode 100644 index 0000000..c9a0f84 Binary files /dev/null and b/assets/icons/r06d.png differ diff --git a/assets/icons/r06n.png b/assets/icons/r06n.png new file mode 100644 index 0000000..d53c701 Binary files /dev/null and b/assets/icons/r06n.png differ diff --git a/assets/icons/s01d.png b/assets/icons/s01d.png new file mode 100644 index 0000000..ba71ced Binary files /dev/null and b/assets/icons/s01d.png differ diff --git a/assets/icons/s01n.png b/assets/icons/s01n.png new file mode 100644 index 0000000..933006d Binary files /dev/null and b/assets/icons/s01n.png differ diff --git a/assets/icons/s02d.png b/assets/icons/s02d.png new file mode 100644 index 0000000..c317029 Binary files /dev/null and b/assets/icons/s02d.png differ diff --git a/assets/icons/s02n.png b/assets/icons/s02n.png new file mode 100644 index 0000000..c317029 Binary files /dev/null and b/assets/icons/s02n.png differ diff --git a/assets/icons/s03d.png b/assets/icons/s03d.png new file mode 100644 index 0000000..c317029 Binary files /dev/null and b/assets/icons/s03d.png differ diff --git a/assets/icons/s03n.png b/assets/icons/s03n.png new file mode 100644 index 0000000..c317029 Binary files /dev/null and b/assets/icons/s03n.png differ diff --git a/assets/icons/s04d.png b/assets/icons/s04d.png new file mode 100644 index 0000000..ba71ced Binary files /dev/null and b/assets/icons/s04d.png differ diff --git a/assets/icons/s04n.png b/assets/icons/s04n.png new file mode 100644 index 0000000..933006d Binary files /dev/null and b/assets/icons/s04n.png differ diff --git a/assets/icons/s05d.png b/assets/icons/s05d.png new file mode 100644 index 0000000..d66cb7d Binary files /dev/null and b/assets/icons/s05d.png differ diff --git a/assets/icons/s05n.png b/assets/icons/s05n.png new file mode 100644 index 0000000..d66cb7d Binary files /dev/null and b/assets/icons/s05n.png differ diff --git a/assets/icons/s06d.png b/assets/icons/s06d.png new file mode 100644 index 0000000..01484c7 Binary files /dev/null and b/assets/icons/s06d.png differ diff --git a/assets/icons/s06n.png b/assets/icons/s06n.png new file mode 100644 index 0000000..01484c7 Binary files /dev/null and b/assets/icons/s06n.png differ diff --git a/assets/icons/t01d.png b/assets/icons/t01d.png new file mode 100644 index 0000000..3dbdfac Binary files /dev/null and b/assets/icons/t01d.png differ diff --git a/assets/icons/t01n.png b/assets/icons/t01n.png new file mode 100644 index 0000000..5dfd158 Binary files /dev/null and b/assets/icons/t01n.png differ diff --git a/assets/icons/t02d.png b/assets/icons/t02d.png new file mode 100644 index 0000000..3dbdfac Binary files /dev/null and b/assets/icons/t02d.png differ diff --git a/assets/icons/t02n.png b/assets/icons/t02n.png new file mode 100644 index 0000000..5dfd158 Binary files /dev/null and b/assets/icons/t02n.png differ diff --git a/assets/icons/t03d.png b/assets/icons/t03d.png new file mode 100644 index 0000000..3dbdfac Binary files /dev/null and b/assets/icons/t03d.png differ diff --git a/assets/icons/t03n.png b/assets/icons/t03n.png new file mode 100644 index 0000000..5dfd158 Binary files /dev/null and b/assets/icons/t03n.png differ diff --git a/assets/icons/t04d.png b/assets/icons/t04d.png new file mode 100644 index 0000000..4edbd52 Binary files /dev/null and b/assets/icons/t04d.png differ diff --git a/assets/icons/t04n.png b/assets/icons/t04n.png new file mode 100644 index 0000000..67b2e09 Binary files /dev/null and b/assets/icons/t04n.png differ diff --git a/assets/icons/t05d.png b/assets/icons/t05d.png new file mode 100644 index 0000000..4edbd52 Binary files /dev/null and b/assets/icons/t05d.png differ diff --git a/assets/icons/t05n.png b/assets/icons/t05n.png new file mode 100644 index 0000000..67b2e09 Binary files /dev/null and b/assets/icons/t05n.png differ diff --git a/assets/icons/u00d.png b/assets/icons/u00d.png new file mode 100644 index 0000000..c9a0f84 Binary files /dev/null and b/assets/icons/u00d.png differ diff --git a/assets/icons/u00n.png b/assets/icons/u00n.png new file mode 100644 index 0000000..c9a0f84 Binary files /dev/null and b/assets/icons/u00n.png differ diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 5d430f2..96d586e 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -291,7 +291,7 @@ ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.contacts01; + PRODUCT_BUNDLE_IDENTIFIER = com.example.weatherApplication; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -415,7 +415,7 @@ ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.contacts01; + PRODUCT_BUNDLE_IDENTIFIER = com.example.weatherApplication; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -434,7 +434,7 @@ ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.contacts01; + PRODUCT_BUNDLE_IDENTIFIER = com.example.weatherApplication; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -468,4 +468,4 @@ /* End XCConfigurationList section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; -} +} \ No newline at end of file diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png index dc9ada4..267cbd1 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png index 28c6bf0..a6f8350 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png index 2ccbfd9..b411f7a 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png index f091b6b..24a6136 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index 4cde121..0b4b191 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png index d0ef06e..b2c0c9e 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png index dcdc230..0d72369 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png index 2ccbfd9..b411f7a 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png index c8f9ed8..3d14607 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png index a6d6b86..9e402b7 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png index a6d6b86..9e402b7 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png index 75b2d16..5c48466 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index c4df70d..9c20b75 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png index 6a84f41..7a1730b 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png index d0e1f58..7e7f79b 100644 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index e2eed25..f40c855 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -11,7 +11,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - contacts_01 + weather_application CFBundlePackageType APPL CFBundleShortVersionString diff --git a/lib/data_proc/cities.dart b/lib/data_proc/cities.dart new file mode 100644 index 0000000..790d235 --- /dev/null +++ b/lib/data_proc/cities.dart @@ -0,0 +1,70 @@ +var citiesData = [ + "Zaxo", + "Umm Qaşr", + "Tozkhurmato", + "Tikrīt", + "Tallkayf", + "Sīnah", + "Sāmarrā’", + "Nāḩīyat Saddat al Hindīyah", + "Ruwāndiz", + "Al-Hamdaniya", + "Mandalī", + "Koysinceq", + "Kifrī", + "Kirkuk", + "Karbala", + "Erbil", + "Hīt", + "Ḩalabjah", + "Ḩadīthah", + "Dihok", + "Jamjamāl", + "Bayjī", + "Baqubah", + "Baynjiwayn", + "Balad", + "Baghdad", + "Az Zubayr", + "Aş Şuwayrah", + "As Sulaymānīyah", + "As Samawah", + "Nāḩiyat ash Shināfīyah", + "Ash Shaţrah", + "Ash Shāmīyah", + "Ar Ruţbah", + "Ar Rumaythah", + "Ramadi", + "‘Aqrah", + "An Nāşirīyah", + "Najaf", + "‘Anat al Qadīmah", + "Imam Qasim", + "Al Musayyib", + "Al Mishkhāb", + "Al Miqdādīyah", + "Al Mawşil al Jadīdah", + "Mosul", + "Al Kūt", + "Kufa", + "Khāliş", + "‘Alī al Gharbī", + "Al Hindīyah", + "Al Ḩillah", + "Al Ḩayy", + "Al Hārithah", + "Nahiyat Ghammas", + "Nāḩiyat al Fuhūd", + "Al Fāw", + "Al Fallūjah", + "Basrah", + "Al ‘Azīzīyah", + "Al ‘Amārah", + "‘Afak", + "Ad Dujayl", + "Ad Dīwānīyah", + "Abū Ghurayb", + "Al Başrah al Qadīmah", + "Sinjār", + "‘Anah" +]; diff --git a/lib/data_proc/current_days.dart b/lib/data_proc/current_days.dart new file mode 100644 index 0000000..16323d9 --- /dev/null +++ b/lib/data_proc/current_days.dart @@ -0,0 +1,360 @@ +/// +/// Code generated by jsonToDartModel https://ashamp.github.io/jsonToDartModel/ +/// +class WeatherAPIDataWeather { +/* +{ + "icon": "c01d", + "code": 800, + "description": "Clear Sky" +} +*/ + + String? icon; + int? code; + String? description; + + WeatherAPIDataWeather({ + this.icon, + this.code, + this.description, + }); + WeatherAPIDataWeather.fromJson(Map json) { + icon = json["icon"]?.toString(); + code = json["code"]?.toInt(); + description = json["description"]?.toString(); + } + Map toJson() { + final Map data = Map(); + data["icon"] = icon; + data["code"] = code; + data["description"] = description; + return data; + } +} + +class WeatherAPIData { +/* +{ + "moonrise_ts": 1634594272, + "wind_cdir": "W", + "rh": 60, + "pres": 1009.29, + "high_temp": 19.9, + "sunset_ts": 1634596376, + "ozone": 293.405, + "moon_phase": 0.985026, + "wind_gust_spd": 12.5, + "snow_depth": 0, + "clouds": 1, + "ts": 1634529660, + "sunrise_ts": 1634556206, + "app_min_temp": 8.8, + "wind_spd": 3.17652, + "pop": 0, + "wind_cdir_full": "west", + "slp": 1019.4, + "moon_phase_lunation": 0.43, + "valid_date": "2021-10-18", + "app_max_temp": 18.9, + "vis": 24.096, + "dewpt": 6.1, + "snow": 0, + "uv": 5.33343, + "weather": { + "icon": "c01d", + "code": 800, + "description": "Clear Sky" + }, + "wind_dir": 277, + "max_dhi": null, + "clouds_hi": 0, + "precip": 0, + "low_temp": 8.8, + "max_temp": 19.9, + "moonset_ts": 1634552290, + "datetime": "2021-10-18", + "temp": 14.6, + "min_temp": 8.7, + "clouds_mid": 0, + "clouds_low": 1 +} +*/ + + int? moonriseTs; + String? windCdir; + int? rh; + double? pres; + double? highTemp; + int? sunsetTs; + double? ozone; + double? moonPhase; + double? windGustSpd; + int? snowDepth; + int? clouds; + int? ts; + int? sunriseTs; + double? appMinTemp; + double? windSpd; + int? pop; + String? windCdirFull; + double? slp; + double? moonPhaseLunation; + String? validDate; + double? appMaxTemp; + double? vis; + double? dewpt; + int? snow; + double? uv; + WeatherAPIDataWeather? weather; + int? windDir; + String? maxDhi; + int? cloudsHi; + int? precip; + double? lowTemp; + double? maxTemp; + int? moonsetTs; + String? datetime; + double? temp; + double? minTemp; + int? cloudsMid; + int? cloudsLow; + + WeatherAPIData({ + this.moonriseTs, + this.windCdir, + this.rh, + this.pres, + this.highTemp, + this.sunsetTs, + this.ozone, + this.moonPhase, + this.windGustSpd, + this.snowDepth, + this.clouds, + this.ts, + this.sunriseTs, + this.appMinTemp, + this.windSpd, + this.pop, + this.windCdirFull, + this.slp, + this.moonPhaseLunation, + this.validDate, + this.appMaxTemp, + this.vis, + this.dewpt, + this.snow, + this.uv, + this.weather, + this.windDir, + this.maxDhi, + this.cloudsHi, + this.precip, + this.lowTemp, + this.maxTemp, + this.moonsetTs, + this.datetime, + this.temp, + this.minTemp, + this.cloudsMid, + this.cloudsLow, + }); + WeatherAPIData.fromJson(Map json) { + moonriseTs = json["moonrise_ts"]?.toInt(); + windCdir = json["wind_cdir"]?.toString(); + rh = json["rh"]?.toInt(); + pres = json["pres"]?.toDouble(); + highTemp = json["high_temp"]?.toDouble(); + sunsetTs = json["sunset_ts"]?.toInt(); + ozone = json["ozone"]?.toDouble(); + moonPhase = json["moon_phase"]?.toDouble(); + windGustSpd = json["wind_gust_spd"]?.toDouble(); + snowDepth = json["snow_depth"]?.toInt(); + clouds = json["clouds"]?.toInt(); + ts = json["ts"]?.toInt(); + sunriseTs = json["sunrise_ts"]?.toInt(); + appMinTemp = json["app_min_temp"]?.toDouble(); + windSpd = json["wind_spd"]?.toDouble(); + pop = json["pop"]?.toInt(); + windCdirFull = json["wind_cdir_full"]?.toString(); + slp = json["slp"]?.toDouble(); + moonPhaseLunation = json["moon_phase_lunation"]?.toDouble(); + validDate = json["valid_date"]?.toString(); + appMaxTemp = json["app_max_temp"]?.toDouble(); + vis = json["vis"]?.toDouble(); + dewpt = json["dewpt"]?.toDouble(); + snow = json["snow"]?.toInt(); + uv = json["uv"]?.toDouble(); + weather = (json["weather"] != null) + ? WeatherAPIDataWeather.fromJson(json["weather"]) + : null; + windDir = json["wind_dir"]?.toInt(); + maxDhi = json["max_dhi"]?.toString(); + cloudsHi = json["clouds_hi"]?.toInt(); + precip = json["precip"]?.toInt(); + lowTemp = json["low_temp"]?.toDouble(); + maxTemp = json["max_temp"]?.toDouble(); + moonsetTs = json["moonset_ts"]?.toInt(); + datetime = json["datetime"]?.toString(); + temp = json["temp"]?.toDouble(); + minTemp = json["min_temp"]?.toDouble(); + cloudsMid = json["clouds_mid"]?.toInt(); + cloudsLow = json["clouds_low"]?.toInt(); + } + Map toJson() { + final Map data = Map(); + data["moonrise_ts"] = moonriseTs; + data["wind_cdir"] = windCdir; + data["rh"] = rh; + data["pres"] = pres; + data["high_temp"] = highTemp; + data["sunset_ts"] = sunsetTs; + data["ozone"] = ozone; + data["moon_phase"] = moonPhase; + data["wind_gust_spd"] = windGustSpd; + data["snow_depth"] = snowDepth; + data["clouds"] = clouds; + data["ts"] = ts; + data["sunrise_ts"] = sunriseTs; + data["app_min_temp"] = appMinTemp; + data["wind_spd"] = windSpd; + data["pop"] = pop; + data["wind_cdir_full"] = windCdirFull; + data["slp"] = slp; + data["moon_phase_lunation"] = moonPhaseLunation; + data["valid_date"] = validDate; + data["app_max_temp"] = appMaxTemp; + data["vis"] = vis; + data["dewpt"] = dewpt; + data["snow"] = snow; + data["uv"] = uv; + if (weather != null) { + data["weather"] = weather!.toJson(); + } + data["wind_dir"] = windDir; + data["max_dhi"] = maxDhi; + data["clouds_hi"] = cloudsHi; + data["precip"] = precip; + data["low_temp"] = lowTemp; + data["max_temp"] = maxTemp; + data["moonset_ts"] = moonsetTs; + data["datetime"] = datetime; + data["temp"] = temp; + data["min_temp"] = minTemp; + data["clouds_mid"] = cloudsMid; + data["clouds_low"] = cloudsLow; + return data; + } +} + +class WeatherAPI { +/* +{ + "data": [ + { + "moonrise_ts": 1634594272, + "wind_cdir": "W", + "rh": 60, + "pres": 1009.29, + "high_temp": 19.9, + "sunset_ts": 1634596376, + "ozone": 293.405, + "moon_phase": 0.985026, + "wind_gust_spd": 12.5, + "snow_depth": 0, + "clouds": 1, + "ts": 1634529660, + "sunrise_ts": 1634556206, + "app_min_temp": 8.8, + "wind_spd": 3.17652, + "pop": 0, + "wind_cdir_full": "west", + "slp": 1019.4, + "moon_phase_lunation": 0.43, + "valid_date": "2021-10-18", + "app_max_temp": 18.9, + "vis": 24.096, + "dewpt": 6.1, + "snow": 0, + "uv": 5.33343, + "weather": { + "icon": "c01d", + "code": 800, + "description": "Clear Sky" + }, + "wind_dir": 277, + "max_dhi": null, + "clouds_hi": 0, + "precip": 0, + "low_temp": 8.8, + "max_temp": 19.9, + "moonset_ts": 1634552290, + "datetime": "2021-10-18", + "temp": 14.6, + "min_temp": 8.7, + "clouds_mid": 0, + "clouds_low": 1 + } + ], + "city_name": "Raleigh", + "lon": "-78.63861", + "timezone": "America/New_York", + "lat": "35.7721", + "country_code": "US", + "state_code": "NC" +} +*/ + + List? data; + String? cityName; + String? lon; + String? timezone; + String? lat; + String? countryCode; + String? stateCode; + + WeatherAPI({ + this.data, + this.cityName, + this.lon, + this.timezone, + this.lat, + this.countryCode, + this.stateCode, + }); + WeatherAPI.fromJson(Map json) { + if (json["data"] != null) { + final v = json["data"]; + final arr0 = []; + v.forEach((v) { + arr0.add(WeatherAPIData.fromJson(v)); + }); + this.data = arr0; + } + cityName = json["city_name"]?.toString(); + lon = json["lon"]?.toString(); + timezone = json["timezone"]?.toString(); + lat = json["lat"]?.toString(); + countryCode = json["country_code"]?.toString(); + stateCode = json["state_code"]?.toString(); + } + Map toJson() { + final Map data = Map(); + if (this.data != null) { + final v = this.data; + final arr0 = []; + v!.forEach((v) { + arr0.add(v!.toJson()); + }); + data["data"] = arr0; + } + data["city_name"] = cityName; + data["lon"] = lon; + data["timezone"] = timezone; + data["lat"] = lat; + data["country_code"] = countryCode; + data["state_code"] = stateCode; + return data; + } +} diff --git a/lib/data_proc/fetch_data_api.dart b/lib/data_proc/fetch_data_api.dart new file mode 100644 index 0000000..27d2470 --- /dev/null +++ b/lib/data_proc/fetch_data_api.dart @@ -0,0 +1,76 @@ +import 'dart:convert'; +import 'package:flutter/cupertino.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:tuple/tuple.dart'; + +import 'current_days.dart'; +import 'package:http/http.dart' as http; + +late LoadingState loadingState; + +class ErrorResponse { + ErrorResponse(this.message, this.statusCode); + String message; + int statusCode; +} + +enum LoadingState { idle, loading, finished } + +class WeatherViewModel extends ChangeNotifier { + late Tuple2 WeatherResponse; + LoadingState loadingState = LoadingState.idle; + final Future _prefs = SharedPreferences.getInstance(); + late String chosedCity; + UsersViewModel() { + WeatherResponse = Tuple2(null, null); + //chosedCity = "Baghdad"; + } + + Future getCity() async { + final SharedPreferences prefs = await _prefs; + chosedCity = prefs.getString("chosedCity") ?? "Baghdad"; + } + + void saveCity() async { + final SharedPreferences prefs = await _prefs; + prefs.setString("chosedCity", chosedCity); + } + + void fetchWeatherData() async { + loadingState = LoadingState.loading; + + await getCity(); + + notifyListeners(); + var response; + WeatherAPI curDay; + + try { + var url = Uri.parse( + 'https://api.weatherbit.io/v2.0/forecast/daily?city=${chosedCity}&days=7&key=6cdc2f711e654daaa22dd0a7de07e768'); + + response = await http.get( + url, + ); + + var json = jsonDecode(response.body); + + curDay = WeatherAPI.fromJson(json); + + WeatherResponse = Tuple2(null, curDay); + loadingState = LoadingState.finished; + notifyListeners(); + } catch (e) { + if (response?.statusCode == 200) { + WeatherResponse = Tuple2( + ErrorResponse('Data is corrupt', response?.statusCode), null); + } else { + WeatherResponse = Tuple2( + ErrorResponse('No Internet\n Try again by pull down to retry', -1), + null); + } + } + loadingState = LoadingState.finished; + notifyListeners(); + } +} diff --git a/lib/main.dart b/lib/main.dart index 2c084ed..324574f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,17 +1,25 @@ -import 'package:flutter/material.dart'; -import 'dart:math' as math; -void main() { - runApp(const MyApp()); -} +import 'dart:async'; -class Contact { - String image; - String name; - String mobileNumber; - DateTime date; - bool isIncoming; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:provider/provider.dart'; +import 'package:tuple/tuple.dart'; +import 'package:weather_application/ui/chose_city.dart'; +import 'package:weather_application/ui/current.dart'; +import 'package:weather_application/ui/error_ui.dart'; +import 'package:weather_application/ui/forecast.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'data_proc/current_days.dart'; +import 'data_proc/fetch_data_api.dart'; - Contact(this.image, this.name, this.mobileNumber, this.date, this.isIncoming); +void main() { + WidgetsFlutterBinding.ensureInitialized(); + SystemChrome.setEnabledSystemUIOverlays( + [SystemUiOverlay.bottom, SystemUiOverlay.top]); + runApp(ChangeNotifierProvider( + create: (context) => WeatherViewModel(), + child: const MyApp(), + )); } class MyApp extends StatelessWidget { @@ -19,13 +27,21 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo 2', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - debugShowCheckedModeBanner: false, - home: const MyHomePage(title: 'Contacts App'), + return FutureBuilder( + future: Init.instance.initialize(), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return MaterialApp(home: Splash()); + } else { + return MaterialApp( + title: 'Weather Application', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: const MyHomePage(title: 'Weather '), + ); + } + }, ); } } @@ -40,216 +56,103 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - int _selectedIndex = 2; - static const TextStyle optionStyle = - TextStyle(fontSize: 30, fontWeight: FontWeight.bold); - static late List _pages; - - _MyHomePageState() { - _pages = [ - buildContactsList(), - buildFavoritesGridView(), - // Text('hello'), - Text( - 'Index 2: School', - style: optionStyle, - ), - ]; - } + late GlobalKey refreshKey; - void _onItemTapped(int index) { - setState(() { - _selectedIndex = index; - }); - } + @override + void initState() { + print('initState'); - var contacts = [ - Contact( - 'https://i.pravatar.cc/300', - 'Ahmed', - '71766137347', - DateTime.now().add( - const Duration(seconds: 3), - ), - true, - ), - Contact( - 'https://i.pravatar.cc/301', - 'Ali', - '71766137347', - DateTime.now().add( - const Duration(days: 1), - ), - false, - ), - Contact( - 'https://i.pravatar.cc/302', - 'Kamal', - '71766137347', - DateTime.now().add( - const Duration(days: 3), - ), - true, - ), - Contact( - 'https://i.pravatar.cc/303', - 'Mohammad', - '71766137347', - DateTime.now().add( - const Duration(days: 5), - ), - true, - ), - Contact( - 'https://i.pravatar.cc/304', - 'Mohammad', - '71766137347', - DateTime.now().add( - const Duration(days: 5), - ), - false, - ), - Contact( - 'https://i.pravatar.cc/305', - 'Hussein', - '71766137347', - DateTime.now().add( - const Duration(days: 6), - ), - false, - ), - Contact( - 'https://i.pravatar.cc/306', - 'Aboud', - '71766137347', - DateTime.now().add( - const Duration(days: 7), - ), - false, - ), - Contact( - 'https://i.pravatar.cc/307', - 'Osama', - '71766137347', - DateTime.now().add( - const Duration(days: 6), - ), - false, - ), - ]; - - Widget buildFavoritesGridView() { - return Column( - children: [ - Text('Favorites'), - Divider(thickness: 4,), - Expanded( - child: GridView.count( - crossAxisCount: 3, - children: List.generate(5, (index) { - var personColor = Color((math.Random().nextDouble() * 0xFFFFFF).toInt()) - .withOpacity(1.0); - return Center( - child: Container( - width: 120, - height: 120, - child: Text( - contacts[index].name[0], - style: TextStyle(fontSize: 40), - ), - alignment: Alignment.center, - decoration: - BoxDecoration(shape: BoxShape.circle, color: personColor), - ), - ); - }), - ), - ), - ], - ); + context.read().getCity(); + context.read().fetchWeatherData(); + // Future.microtask(() => context.read().fetchWeatherData()); + + super.initState(); + refreshKey = GlobalKey(); } - Widget buildContactItem(Contact _contact) { - return Card( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - CircleAvatar( - backgroundImage: NetworkImage(_contact.image), - ), - Padding( - padding: const EdgeInsets.all(16), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _contact.name, - style: const TextStyle(fontWeight: FontWeight.bold), - ), - Text(_contact.mobileNumber), - ], - ), - ), - Text(_contact.date.toIso8601String().split('T').first), - Expanded( - child: Container(), + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color.fromRGBO(28, 46, 74, 1), + extendBodyBehindAppBar: false, + appBar: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + title: Text( + widget.title, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 30, ), - if (_contact.isIncoming) - Icon( - Icons.arrow_downward, - color: Colors.red, - ) - else - Icon( - Icons.arrow_upward, - color: Colors.green, - ) + ), + actions: [ + IconButton( + onPressed: () async { + dynamic result = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ChoseCity( + context.read().chosedCity)), + ); + + if (result != null) { + setState(() { + context.read().chosedCity = result; + context.read().saveCity(); + context.read().fetchWeatherData(); + }); + } + }, + icon: Icon(Icons.location_on)) ], ), - ), - ); - } - - Widget buildContactsList() { - return ListView.builder( - itemBuilder: (_context, index) { - return buildContactItem(contacts[index]); - }, - itemCount: contacts.length, - ); + body: RefreshIndicator( + key: refreshKey, + onRefresh: () async { + context.read().fetchWeatherData(); + }, + child: Center(child: Consumer( + builder: (context, weatherViewModel, child) { + if (weatherViewModel.loadingState == LoadingState.loading) { + return const Center(child: CircularProgressIndicator()); + } else if (weatherViewModel.WeatherResponse.item1 != null) { + return GetError( + context, weatherViewModel.WeatherResponse.item1); + } + return SingleChildScrollView( + child: Column( + children: [ + BuildCurrentCard( + context, weatherViewModel.WeatherResponse.item2), + BuildForeCastDays( + context, weatherViewModel.WeatherResponse.item2) + ], + ), + ); + }, + )), + )); } +} +class Splash extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: _pages[_selectedIndex], - ), - bottomNavigationBar: BottomNavigationBar( - items: const [ - BottomNavigationBarItem( - icon: Icon(Icons.home), - label: 'Recent', - ), - BottomNavigationBarItem( - icon: Icon(Icons.favorite), - label: 'Favorites', - ), - BottomNavigationBarItem( - icon: Icon(Icons.access_time_outlined), - label: 'School', - activeIcon: Icon(Icons.access_time_filled) - ), - ], - currentIndex: _selectedIndex, - selectedItemColor: Colors.amber[800], - onTap: _onItemTapped, - ), + backgroundColor: Color(0xe1f5fe).withOpacity(1.0), + body: Center(child: Image.asset('assets/icon_app.png')), ); } } + +class Init { + Init._(); + static final instance = Init._(); + + Future initialize() async { + // This is where you can initialize the resources needed by your app while + // the splash screen is displayed. Remove the following example because + // delaying the user experience is a bad design practice! + await Future.delayed(const Duration(seconds: 3)); + } +} diff --git a/lib/ui/chose_city.dart b/lib/ui/chose_city.dart new file mode 100644 index 0000000..367d655 --- /dev/null +++ b/lib/ui/chose_city.dart @@ -0,0 +1,70 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:csv/csv.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:weather_application/data_proc/cities.dart'; + +class ChoseCity extends StatefulWidget { + const ChoseCity(String chosedCity, {Key? key}) : super(key: key); + + @override + State createState() => _ChoseCityState(); +} + +class _ChoseCityState extends State { + @override + void initState() { + citiesData.sort(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color.fromRGBO(28, 46, 74, 1), + extendBodyBehindAppBar: false, + appBar: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + title: const Text('Select City'), + ), + body: Padding( + padding: const EdgeInsets.all(1), + child: ListView.builder( + itemCount: citiesData.length, + itemBuilder: (context, index) { + return ListTile( + title: Container( + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.all(Radius.circular(5)), + gradient: LinearGradient( + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + Colors.cyan, + Colors.blue[700]!, + ], + )), + height: 50, + child: Center( + child: Text( + citiesData[index].toString(), + style: const TextStyle( + color: Colors.white, fontWeight: FontWeight.bold), + ), + ), + ), + onTap: () { + print(index); + Navigator.pop(context, citiesData[index]); + }, + ); + }, + ), + ), + ); + } +} diff --git a/lib/ui/current.dart b/lib/ui/current.dart new file mode 100644 index 0000000..05e71c9 --- /dev/null +++ b/lib/ui/current.dart @@ -0,0 +1,104 @@ +import 'package:flutter/material.dart'; +import 'package:weather_application/data_proc/current_days.dart'; + +Widget BuildCurrentCard(BuildContext context, WeatherAPI? wAPI) { + return Padding( + padding: const EdgeInsets.all(12), + child: Container( + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: const BorderRadius.all(Radius.circular(20)), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: const Offset(0, 3), // changes position of shadow + ), + ], + gradient: LinearGradient( + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + Colors.cyan, + Colors.blue[700]!, + ], + )), + width: MediaQuery.of(context).size.width, + height: 300, + child: Padding( + padding: const EdgeInsets.all(15), + child: Center( + child: Column( + children: [ + Text( + ' ${wAPI?.cityName}', + style: const TextStyle( + fontSize: 20, + color: Colors.white, + fontWeight: FontWeight.normal, + fontFamily: "Roboto", + ), + ), + const Padding( + padding: EdgeInsets.all(8.0), + child: Text( + 'Today', + style: TextStyle( + fontSize: 15, + color: Colors.white70, + fontWeight: FontWeight.normal, + fontFamily: "Roboto", + ), + ), + ), + ///////// + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '${wAPI?.data?[0]?.temp?.round().toString()}\u2103', + style: const TextStyle( + fontSize: 100, + color: Colors.white, + fontWeight: FontWeight.normal, + fontFamily: "Roboto", + ), + ), + Expanded(child: Container()), + Column( + children: [ + Image.asset( + 'assets/icons/${wAPI?.data?[0]?.weather?.icon}.png', + scale: 1, + ), + Text( + ' ${wAPI?.data?[0]?.weather?.description}', + style: const TextStyle( + fontSize: 20, + color: Colors.white, + fontWeight: FontWeight.normal, + fontFamily: "Roboto", + ), + ), + ], + ) + ], + ), + + Expanded(child: Container()), + Text( + '${wAPI?.data?[0]?.validDate}', + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontFamily: "Roboto", + ), + ), + ], + ), + ), + ), + ), + ); +} diff --git a/lib/ui/error_ui.dart b/lib/ui/error_ui.dart new file mode 100644 index 0000000..6e18154 --- /dev/null +++ b/lib/ui/error_ui.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; +import 'package:weather_application/data_proc/fetch_data_api.dart'; + +Widget GetError(BuildContext context, ErrorResponse? item1) { + return SingleChildScrollView( + child: Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + child: Center( + child: Text( + '${item1?.message} ', + style: const TextStyle( + color: Colors.white, + fontSize: 50, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + ), + ), + ); +} diff --git a/lib/ui/forecast.dart b/lib/ui/forecast.dart new file mode 100644 index 0000000..b949758 --- /dev/null +++ b/lib/ui/forecast.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; +import 'package:weather_application/data_proc/current_days.dart'; + +import 'forecast_card.dart'; + +Widget BuildForeCastDays(BuildContext context, WeatherAPI? wAPI) { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 10, 0, 0), + child: Container( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 10), + decoration: BoxDecoration( + color: const Color.fromRGBO(28, 46, 74, 1), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(30), + topRight: Radius.circular(30), + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: const Offset(0, 3), // changes position of shadow + ), + ], + ), + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height - 410, + child: Column( + children: [ + const Padding( + padding: EdgeInsets.all(10), + child: Center( + child: Text( + "Next Seven Days", + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 20, + ), + ), + ), + ), + Expanded(child: BuildForeCastCard(context, wAPI)), + ], + ), + ), + ); +} diff --git a/lib/ui/forecast_card.dart b/lib/ui/forecast_card.dart new file mode 100644 index 0000000..128710f --- /dev/null +++ b/lib/ui/forecast_card.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; +import 'package:weather_application/data_proc/current_days.dart'; +import 'package:intl/intl.dart'; + +Widget BuildForeCastCard(BuildContext context, WeatherAPI? wAPI) { + return Padding( + padding: const EdgeInsets.all(10.0), + child: GridView.builder( + itemCount: 7, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, crossAxisSpacing: 4, mainAxisSpacing: 4), + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.all(Radius.circular(20)), + gradient: LinearGradient( + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + Colors.cyan, + Colors.blue[700]!, + ], + )), + width: 40, + height: 20, + child: Padding( + padding: const EdgeInsets.all(15), + child: Center( + child: Column( + children: [ + Text( + DateFormat('EEEE').format( + DateTime.parse(wAPI?.data?[index]?.validDate ?? ' ')), + style: const TextStyle( + fontSize: 15, + color: Colors.white, + fontWeight: FontWeight.normal, + fontFamily: "Roboto", + ), + ), + ///////// + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '${wAPI?.data?[index]?.temp?.round().toString()}\u2103', + style: const TextStyle( + fontSize: 20, + color: Colors.white, + fontWeight: FontWeight.normal, + fontFamily: "Roboto", + ), + ), + Expanded(child: Container()), + Column( + children: [ + Image.asset( + 'assets/icons/${wAPI?.data?[index]?.weather?.icon}.png', + scale: 2, + ), + Text( + ' ${wAPI?.data?[index]?.weather?.description}', + style: const TextStyle( + fontSize: 10, + color: Colors.white, + fontWeight: FontWeight.normal, + fontFamily: "Roboto", + ), + ), + ], + ) + ], + ), + + Expanded(child: Container()), + Text( + '${wAPI?.data?[index]?.validDate}', + style: const TextStyle( + color: Colors.white54, + fontWeight: FontWeight.normal, + fontFamily: "Roboto", + ), + ), + ], + ), + ), + ), + ), + ); + }, + ), + ); +} diff --git a/pubspec.lock b/pubspec.lock index 750761f..9c203a2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,20 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.6" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" async: dependency: transitive description: @@ -43,6 +57,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + csv: + dependency: "direct main" + description: + name: csv + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.0" cupertino_icons: dependency: "direct main" description: @@ -57,30 +85,84 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" - flutter_lints: - dependency: "direct dev" + flutter_launcher_icons: + dependency: "direct main" description: - name: flutter_lints + name: flutter_launcher_icons url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "0.9.2" + flutter_native_splash: + dependency: "direct main" + description: + name: flutter_native_splash + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.4" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" - lints: + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.8" + intl: + dependency: "direct main" + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.0" + js: dependency: transitive description: - name: lints + name: js url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "0.6.3" matcher: dependency: transitive description: @@ -95,6 +177,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.7.0" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" path: dependency: transitive description: @@ -102,6 +191,111 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "4.4.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.1" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1+1" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" sky_engine: dependency: transitive description: flutter @@ -149,6 +343,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.2" + tuple: + dependency: "direct main" + description: + name: tuple + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" typed_data: dependency: transitive description: @@ -156,6 +357,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + universal_io: + dependency: transitive + description: + name: universal_io + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" vector_math: dependency: transitive description: @@ -163,5 +371,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.10" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "5.3.1" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" sdks: - dart: ">=2.12.0 <3.0.0" + dart: ">=2.14.0 <3.0.0" + flutter: ">=2.5.0" diff --git a/pubspec.yaml b/pubspec.yaml index 1c93cc7..e75545f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,4 +1,4 @@ -name: contacts_01 +name: weather_application description: A new Flutter project. # The following line prevents the package from being accidentally published to @@ -34,11 +34,24 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 + http: ^0.13.4 + tuple: ^2.0.0 + provider: ^6.0.1 + intl: ^0.17.0 + csv: ^5.0.0 + shared_preferences: ^2.0.8 + flutter_launcher_icons: ^0.9.2 + flutter_native_splash: ^1.2.4 + dev_dependencies: flutter_test: sdk: flutter +flutter_icons: + android: "launcher_icon" + ios: true + image_path: "assets/icon_app.png" # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your @@ -58,9 +71,10 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg + assets: + - assets/icons/ + - assets/cities_all.csv + - assets/icon_app.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. diff --git a/screenshots/1 (1).png b/screenshots/1 (1).png new file mode 100644 index 0000000..04415da Binary files /dev/null and b/screenshots/1 (1).png differ diff --git a/screenshots/1 (2).png b/screenshots/1 (2).png new file mode 100644 index 0000000..a88553b Binary files /dev/null and b/screenshots/1 (2).png differ diff --git a/screenshots/1 (3).png b/screenshots/1 (3).png new file mode 100644 index 0000000..2ef7e31 Binary files /dev/null and b/screenshots/1 (3).png differ diff --git a/screenshots/1 (4).png b/screenshots/1 (4).png new file mode 100644 index 0000000..2e871eb Binary files /dev/null and b/screenshots/1 (4).png differ diff --git a/screenshots/1 (5).png b/screenshots/1 (5).png new file mode 100644 index 0000000..da252da Binary files /dev/null and b/screenshots/1 (5).png differ diff --git a/screenshots/1 (6).png b/screenshots/1 (6).png new file mode 100644 index 0000000..2f381a2 Binary files /dev/null and b/screenshots/1 (6).png differ diff --git a/test/widget_test.dart b/test/widget_test.dart index 5f578bd..c012326 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:contacts_01/main.dart'; +import 'package:weather_application/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { diff --git a/web/index.html b/web/index.html index d2606e7..0f3d075 100644 --- a/web/index.html +++ b/web/index.html @@ -23,10 +23,10 @@ - + - contacts_01 + weather_application diff --git a/web/manifest.json b/web/manifest.json index 9631a79..6620749 100644 --- a/web/manifest.json +++ b/web/manifest.json @@ -1,6 +1,6 @@ { - "name": "contacts_01", - "short_name": "contacts_01", + "name": "weather_application", + "short_name": "weather_application", "start_url": ".", "display": "standalone", "background_color": "#0175C2",