diff --git a/.gitignore b/.gitignore index d70ff3a..82f9a8e 100755 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ *.iws .idea/ + # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. @@ -31,7 +32,6 @@ .pub-cache/ .pub/ /build/ - # Web related lib/generated_plugin_registrant.dart @@ -40,3 +40,4 @@ app.*.symbols # Obfuscation related app.*.map.json +google-services.json diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..f4d8934 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,12 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +google-services.json \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..74ef2d1 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,75 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +def GOOGLE_MAPS_API_KEY = localProperties.getProperty('GOOGLE_MAPS_API_KEY') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'com.google.gms.google-services' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + + +android { + compileSdkVersion 33 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.hershel.parental_control" + minSdkVersion 29 + targetSdkVersion 33 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + multiDexEnabled true + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + manifestPlaceholders = [GOOGLE_MAPS_API_KEY: GOOGLE_MAPS_API_KEY] + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + buildTypes { + release { + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation platform('com.google.firebase:firebase-bom:26.6.0') + implementation 'androidx.window:window:1.0.0' + implementation 'androidx.window:window-java:1.0.0' + +} diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..d2d26f6 --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,108 @@ +{ + "project_info": { + "project_number": "737237983254", + "project_id": "parental-control-100c8", + "storage_bucket": "parental-control-100c8.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:737237983254:android:55a33cd72d9eb27c0b5537", + "android_client_info": { + "package_name": "com.hershel.parental_admin_child" + } + }, + "oauth_client": [ + { + "client_id": "737237983254-v5rmcfvnaqg3j96uldvqjs5h41ts6vo1.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.hershel.parental_admin_child", + "certificate_hash": "749f39333bd4a3da6b47014840379d9efa283393" + } + }, + { + "client_id": "737237983254-n94tmj88u9rprss8dkshdbbpp1vok9u5.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDfXK1FiSSGZAC-HwReX4fEqrvbBEwAQeU" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "737237983254-n94tmj88u9rprss8dkshdbbpp1vok9u5.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:737237983254:android:5d81d3ade492188a0b5537", + "android_client_info": { + "package_name": "com.hershel.parental_control" + } + }, + "oauth_client": [ + { + "client_id": "737237983254-683he00o55lqf7dfit86cc0ei68nsg1k.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.hershel.parental_control", + "certificate_hash": "709516926153479881057f30a3cdf5577f5883d4" + } + }, + { + "client_id": "737237983254-fskmhe8j4fer38j5m69m0a7fafc7grmm.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.hershel.parental_control", + "certificate_hash": "f397cf064cbfc1cc234a79c0cffe2ffee4b08ff5" + } + }, + { + "client_id": "737237983254-gao9r1ftj3gueve68usl15ao7chm0im6.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.hershel.parental_control", + "certificate_hash": "684020f33706172c249d021dfa363897dca000ca" + } + }, + { + "client_id": "737237983254-kn2dt82baios4pdaekn7uvu8t442r0vn.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.hershel.parental_control", + "certificate_hash": "749f39333bd4a3da6b47014840379d9efa283393" + } + }, + { + "client_id": "737237983254-n94tmj88u9rprss8dkshdbbpp1vok9u5.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDfXK1FiSSGZAC-HwReX4fEqrvbBEwAQeU" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "737237983254-n94tmj88u9rprss8dkshdbbpp1vok9u5.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/local.properties b/android/app/local.properties new file mode 100644 index 0000000..3a0e592 --- /dev/null +++ b/android/app/local.properties @@ -0,0 +1,8 @@ +## This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# Location of the SDK. This is only used by Gradle. +# For customization when using a Version Control System, please read the +# header note. +#Wed Mar 10 15:11:59 EET 2021 +sdk.dir=C\:\\Users\\jordy\\AppData\\Local\\Android\\Sdk diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..2d35de1 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..0749612 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/ic_parent_control-playstore.png b/android/app/src/main/ic_parent_control-playstore.png new file mode 100644 index 0000000..c68f9e1 Binary files /dev/null and b/android/app/src/main/ic_parent_control-playstore.png differ diff --git a/android/app/src/main/kotlin/com/hershel/parental_control/MainActivity.kt b/android/app/src/main/kotlin/com/hershel/parental_control/MainActivity.kt new file mode 100644 index 0000000..a43861c --- /dev/null +++ b/android/app/src/main/kotlin/com/hershel/parental_control/MainActivity.kt @@ -0,0 +1,6 @@ +package com.hershel.parental_control + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..c326fc1 --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/parental_launch.png b/android/app/src/main/res/drawable/parental_launch.png new file mode 100644 index 0000000..669e381 Binary files /dev/null and b/android/app/src/main/res/drawable/parental_launch.png differ diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_parent_control.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_parent_control.xml new file mode 100644 index 0000000..5802492 --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_parent_control.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_parent_control_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_parent_control_round.xml new file mode 100644 index 0000000..5802492 --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_parent_control_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_parent_control.png b/android/app/src/main/res/mipmap-hdpi/ic_parent_control.png new file mode 100644 index 0000000..5726c43 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_parent_control.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_parent_control_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_parent_control_foreground.png new file mode 100644 index 0000000..f83392b Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_parent_control_foreground.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_parent_control_round.png b/android/app/src/main/res/mipmap-hdpi/ic_parent_control_round.png new file mode 100644 index 0000000..472d363 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_parent_control_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_parent_control.png b/android/app/src/main/res/mipmap-mdpi/ic_parent_control.png new file mode 100644 index 0000000..b95f78d Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_parent_control.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_parent_control_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_parent_control_foreground.png new file mode 100644 index 0000000..1e5109b Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_parent_control_foreground.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_parent_control_round.png b/android/app/src/main/res/mipmap-mdpi/ic_parent_control_round.png new file mode 100644 index 0000000..ad8309f Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_parent_control_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_parent_control.png b/android/app/src/main/res/mipmap-xhdpi/ic_parent_control.png new file mode 100644 index 0000000..c737442 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_parent_control.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_parent_control_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_parent_control_foreground.png new file mode 100644 index 0000000..beef7e2 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_parent_control_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_parent_control_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_parent_control_round.png new file mode 100644 index 0000000..5925b12 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_parent_control_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_parent_control.png b/android/app/src/main/res/mipmap-xxhdpi/ic_parent_control.png new file mode 100644 index 0000000..abc215e Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_parent_control.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_parent_control_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_parent_control_foreground.png new file mode 100644 index 0000000..0008963 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_parent_control_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_parent_control_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_parent_control_round.png new file mode 100644 index 0000000..2af0bbf Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_parent_control_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_parent_control.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_parent_control.png new file mode 100644 index 0000000..e597092 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_parent_control.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_parent_control_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_parent_control_foreground.png new file mode 100644 index 0000000..c1a9c8c Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_parent_control_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_parent_control_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_parent_control_round.png new file mode 100644 index 0000000..c627dd9 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_parent_control_round.png differ diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..27acd37 --- /dev/null +++ b/android/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #3A4EDC + \ No newline at end of file diff --git a/android/app/src/main/res/values/ic_parent_control_background.xml b/android/app/src/main/res/values/ic_parent_control_background.xml new file mode 100644 index 0000000..ef753de --- /dev/null +++ b/android/app/src/main/res/values/ic_parent_control_background.xml @@ -0,0 +1,4 @@ + + + #3A4EDC + \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..cad47b6 --- /dev/null +++ b/android/app/src/main/res/values/strings.xml @@ -0,0 +1,6 @@ + + + Parental Control + 176011390810650 + fb176011390810650 + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..1f83a33 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..2d35de1 --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..c5502d6 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,32 @@ +buildscript { + ext.kotlin_version = '1.8.10' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.1.3' + classpath 'com.google.gms:google-services:4.3.15' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..a673820 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true +android.enableR8=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..752ce5b --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-all.zip diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..44e62bc --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/android/settings_aar.gradle b/android/settings_aar.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/android/settings_aar.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/lib/app/config/geo_location.dart b/lib/app/config/geo_location.dart index 5b3bdfa..40665c4 100644 --- a/lib/app/config/geo_location.dart +++ b/lib/app/config/geo_location.dart @@ -99,24 +99,24 @@ class _GeoState extends State { @override Widget build(BuildContext context) { return Container( - height: 250, - child: Center( - child: GoogleMap( - initialCameraPosition: CameraPosition( - target: LatLng(widget.initialPosition.latitude, - widget.initialPosition.longitude), - zoom: 15), - mapType: MapType.normal, - myLocationEnabled: true, - onMapCreated: (GoogleMapController controller) { - _controller.complete(controller); - setState(() { - markers[MarkerId(allMarkers.first.markerId.value)] = - allMarkers.first; - }); - }, - markers: Set.of(allMarkers), - ), + height: 300, + margin: EdgeInsets.all(10), + child: GoogleMap( + padding: EdgeInsets.all(10), + mapType: MapType.normal, + myLocationEnabled: true, + markers: Set.of(allMarkers), + initialCameraPosition: CameraPosition( + target: LatLng(widget.initialPosition.latitude, + widget.initialPosition.longitude), + zoom: 15), + onMapCreated: (GoogleMapController controller) { + _controller.complete(controller); + setState(() { + markers[MarkerId(allMarkers.first.markerId.value)] = + allMarkers.first; + }); + }, ), ); } diff --git a/lib/app/pages/notification_page.dart b/lib/app/pages/notification_page.dart index d6d210e..dcaf3dc 100644 --- a/lib/app/pages/notification_page.dart +++ b/lib/app/pages/notification_page.dart @@ -5,6 +5,7 @@ import 'package:parental_control/models/notification_model.dart'; import 'package:parental_control/services/auth.dart'; import 'package:parental_control/services/database.dart'; import 'package:parental_control/services/notification_service.dart'; +import 'package:parental_control/theme/theme.dart'; import 'package:provider/provider.dart'; import '../../common_widgets/show_exeption_alert.dart'; @@ -104,7 +105,7 @@ class _NotificationPageState extends State { }, direction: DismissDirection.endToStart, child: Card( - color: Colors.indigo, + color: CustomColors.indigoLight, child: Padding( padding: EdgeInsets.all(8.0), child: ListTile( diff --git a/lib/app/pages/parent_page.dart b/lib/app/pages/parent_page.dart index dcf3f82..4f36c0e 100644 --- a/lib/app/pages/parent_page.dart +++ b/lib/app/pages/parent_page.dart @@ -1,11 +1,15 @@ import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; +import 'package:parental_control/app/config/geo_full.dart'; +import 'package:parental_control/app/config/geo_location.dart'; import 'package:parental_control/app/pages/child_details_page.dart'; import 'package:parental_control/app/pages/edit_child_page.dart'; import 'package:parental_control/app/pages/notification_page.dart'; import 'package:parental_control/app/pages/setting_page.dart'; import 'package:parental_control/common_widgets/child_horizontal_view.dart'; import 'package:parental_control/common_widgets/empty_content.dart'; +import 'package:parental_control/common_widgets/feature_widget.dart'; +import 'package:parental_control/common_widgets/loading_map.dart'; import 'package:parental_control/models/child_model.dart'; import 'package:parental_control/services/auth.dart'; import 'package:parental_control/services/database.dart'; @@ -16,13 +20,8 @@ import 'package:parental_control/theme/theme.dart'; import 'package:provider/provider.dart'; import 'package:showcaseview/showcaseview.dart'; -import '../config/geo_full.dart'; -import '../config/geo_location.dart'; - enum MapScreenState { Full, Small } -//TODO:Display different commands Focus mode Cards etc - class ParentPage extends StatefulWidget { const ParentPage({Key? key, this.auth}) : super(key: key); @@ -35,8 +34,7 @@ class ParentPage extends StatefulWidget { _ParentPageState createState() => _ParentPageState(); } -class _ParentPageState extends State - with SingleTickerProviderStateMixin { +class _ParentPageState extends State with SingleTickerProviderStateMixin { late Geo geo; /// Variables @@ -73,9 +71,8 @@ class _ParentPageState extends State }); _isShowCaseActivated == false - ? WidgetsBinding.instance.addPostFrameCallback((_) => - ShowCaseWidget.of(context) - .startShowCase([_settingsKey, _childListKey, _addKey])) + ? WidgetsBinding.instance.addPostFrameCallback( + (_) => ShowCaseWidget.of(context).startShowCase([_settingsKey, _childListKey, _addKey])) : null; } @@ -86,14 +83,13 @@ class _ParentPageState extends State return mapScreenState == MapScreenState.Small ? Scaffold( - body: _buildParentPageContent(context, auth), + body: _buildParentPageContent(context, auth, database), floatingActionButton: Showcase( key: _addKey, textColor: Colors.indigo, description: 'Add a new child here ', child: FloatingActionButton( - onPressed: () => EditChildPage.show(context, - database: Provider.of(context, listen: false)), + onPressed: () => EditChildPage.show(context, database: Provider.of(context, listen: false)), child: const Icon(Icons.add), ), ), @@ -101,177 +97,137 @@ class _ParentPageState extends State : _buildMapFullScreen(database); } - Widget _buildParentPageContent(BuildContext context, AuthBase auth) { - final database = Provider.of(context, listen: false); - return Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.20, - width: double.infinity, - decoration: BoxDecoration( - color: Colors.indigo, - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(20), - bottomRight: Radius.circular(20))), - padding: const EdgeInsets.only(top: 25.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisSize: MainAxisSize.max, - children: [ - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const Text( - "Time's Up", - style: TextStyle( - fontWeight: FontWeight.w800, - color: Colors.white38, - fontSize: 22), - ), - OutlinedButton( - onPressed: () => SettingsPage.show(context, auth), - child: Showcase( - key: _settingsKey, - textColor: Colors.indigo, - description: 'change the settings here', - showArrow: true, - child: Icon( - Icons.settings, - color: Colors.white, - ), - ), - ) - ], - ), - ), - const SizedBox(height: 8), - Container( - margin: const EdgeInsets.symmetric(horizontal: 10), - height: 45, - decoration: BoxDecoration( - color: Colors.grey[300], - borderRadius: BorderRadius.circular( - 10.0, - ), + Widget _buildParentPageContent(BuildContext context, AuthBase auth, Database database) { + return NestedScrollView( + headerSliverBuilder: (context, value) { + return [ + SliverAppBar( + backgroundColor: CustomColors.indigoDark, + expandedHeight: MediaQuery.of(context).size.height * 0.12, + shape: ContinuousRectangleBorder( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(30), bottomRight: Radius.circular(30))), + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Time's Up", + style: TextStyle(fontWeight: FontWeight.w800, color: CustomColors.indigoLight, fontSize: 22), ), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 6), - child: TabBar( - physics: BouncingScrollPhysics(), - controller: _tabController, - // give the indicator a decoration (color and border radius) - indicator: BoxDecoration( - borderRadius: BorderRadius.circular( - 10.0, - ), + OutlinedButton( + style: OutlinedButton.styleFrom(side: BorderSide.none), + onPressed: () => SettingsPage.show(context, auth), + child: Showcase( + key: _settingsKey, + textColor: Colors.indigo, + description: 'change the settings here', + showArrow: true, + child: Icon( + Icons.settings, color: Colors.white, ), + ), + ) + ], + ), + pinned: true, + floating: true, + bottom: TabBar( + indicatorPadding: EdgeInsets.all(4.0), + physics: BouncingScrollPhysics(), + controller: _tabController, + // give the indicator a decoration (color and border radius) + indicator: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: Colors.white, + ), - labelColor: Colors.indigo, - unselectedLabelColor: Colors.white, - tabs: [ - // first tab [you can add an icon using the icon property] - Tab( - text: 'Control', - ), + labelColor: Colors.indigo, + unselectedLabelColor: Colors.white, + tabs: [ + // first tab [you can add an icon using the icon property] + Tab( + text: 'Control', + ), - // second tab [you can add an icon using the icon property] - Tab( - text: 'Notifications', - ), - ], - ), + // second tab [you can add an icon using the icon property] + Tab( + text: 'Notifications', ), - ), - ], + ], + ), ), - ), - - /// Tab bar view here - Expanded( - child: TabBarView( - physics: NeverScrollableScrollPhysics(), - controller: _tabController, - children: [ - // first tab bar view widget - CustomScrollView( - physics: BouncingScrollPhysics(), - slivers: [ - SliverList( - delegate: SliverChildListDelegate( - [ - ListTile( - title: Text( - 'My Children', - style: TextStyle(color: Colors.indigo), - ), - subtitle: Text( - 'Choose child to get more infos ', - style: TextStyle(color: Colors.grey.shade400), + ]; + }, + body: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + /// Tab bar view here + Expanded( + child: TabBarView( + physics: NeverScrollableScrollPhysics(), + controller: _tabController, + children: [ + // first tab bar view widget + CustomScrollView( + physics: BouncingScrollPhysics(), + slivers: [ + SliverList( + delegate: SliverChildListDelegate( + [ + ListTile( + title: Text( + 'My Children', + style: TextStyle(color: Colors.indigo), + ), + subtitle: Text( + 'Choose child to get more infos - scroll right ', + style: TextStyle(color: Colors.grey.shade400), + ), + trailing: Icon( + Icons.info_outline_rounded, + color: Colors.deepOrangeAccent.shade100, + ), + ).p8, + SizedBox(height: 3), + _buildChildrenList(database), + _header(), + Container( + margin: EdgeInsets.all(4), + decoration: BoxDecoration( + borderRadius: const BorderRadius.all( + Radius.circular(10), + ), + color: Colors.black.withOpacity(0.14), + ), + child: GestureDetector( + onLongPress: () => setState(() { + mapScreenState = MapScreenState.Full; + }), + child: Consumer(builder: (_, position, __) { + return (position != null) ? Geo(position, database) : LoadingMap(); + }), + ), ), - trailing: Icon( - Icons.info_outline_rounded, - color: Colors.deepOrangeAccent.shade100, + const SizedBox(height: 8), + FeatureWidget( + title: '-- 00 h:00 min --', + icon: Icons.access_alarm, ), - ).p8, - Divider( - height: 5, - color: Colors.grey.withOpacity(0.1), - thickness: 3), - SizedBox(height: 3), - _buildChildrenList(database), - Divider( - height: 5, - color: Colors.grey.withOpacity(0.1), - thickness: 3), - _header(), - GestureDetector( - onLongPress: () { - setState(() { - mapScreenState = MapScreenState.Full; - }); - }, - child: - Consumer(builder: (_, position, __) { - return (position != null) - ? Geo(position, database) - : Container( - height: 250, - decoration: BoxDecoration( - borderRadius: const BorderRadius.all( - Radius.circular(16)), - color: Colors.black.withOpacity(0.14)), - ); - }), - ), - const SizedBox(height: 8), - const Padding( - padding: EdgeInsets.all(45.0), - child: EmptyContent(), - ), - ], + ], + ), ), - ), - ], - ), + ], + ), - /// Second tab bar view widget - /// - /// - Provider( - create: (_) => NotificationService(), - builder: (context, __) => - NotificationPage.create(context, widget.auth!), - ), - ], + Provider( + create: (_) => NotificationService(), + builder: (context, __) => NotificationPage.create(context, widget.auth!), + ), + ], + ), ), - ), - ], + ], + ), ); } @@ -281,50 +237,44 @@ class _ParentPageState extends State description: 'Tap on the child to display infos', key: _childListKey, child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(8)), - color: Colors.white), - //color: Colors.grey, - height: 160.0, - child: StreamBuilder>( - stream: database.childrenStream(), - builder: (context, AsyncSnapshot snapshot) { - final data = snapshot.data; - if (snapshot.hasData) { - if (data != null && data.isNotEmpty) { - return ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: data.length, - itemBuilder: (context, index) { - return Kids( - image_location: data[index]?.image, - image_caption: data[index]?.name, - onPressed: () => - ChildDetailsPage.show(context, data[index]!)); - }, - ); - } else { - return EmptyContent(); - } - } else if (snapshot.hasError) { - print(snapshot.error); - return EmptyContent( - title: 'Something went wrong ', - message: 'Can\'t load items right now', + decoration: CustomDecoration.withShadowDecoration, + height: 160.0, + child: StreamBuilder>( + stream: database.childrenStream(), + builder: (context, AsyncSnapshot snapshot) { + final data = snapshot.data; + if (snapshot.hasData) { + if (data != null && data.isNotEmpty) { + return ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: data.length, + itemBuilder: (context, index) { + return Kids( + image_location: data[index]?.image, + image_caption: data[index]?.name, + onPressed: () => ChildDetailsPage.show(context, data[index]!)); + }, ); + } else { + return EmptyContent(); } - return ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: 3, - itemBuilder: (context, index) { - return Kids( - image_location: null, - image_caption: null, - onPressed: null); - }, + } else if (snapshot.hasError) { + print(snapshot.error); + return EmptyContent( + title: 'Something went wrong ', + message: 'Can\'t load items right now', ); - }, - )), + } + return ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: 3, + itemBuilder: (context, index) { + return Kids(image_location: null, image_caption: null, onPressed: null); + }, + ); + }, + ), + ), ); } @@ -336,12 +286,12 @@ class _ParentPageState extends State padding: EdgeInsets.only(top: 20.0), child: Text( "Follow your child's location ", - style: TextStyle(color: Colors.indigo), + style: TextStyle(color: CustomColors.indigoLight), ), ), Text( 'Long Press the map to open the full screen mode', - style: TextStyle(color: Colors.grey.shade400), + style: TextStyle(color: CustomColors.greenPrimary), ), ], ).p16; @@ -350,9 +300,7 @@ class _ParentPageState extends State Widget _buildMapFullScreen(database) { return Scaffold( body: Consumer(builder: (_, position, __) { - return (position != null) - ? GeoFull(position, database) - : Center(child: CircularProgressIndicator()); + return (position != null) ? GeoFull(position, database) : Center(child: CircularProgressIndicator()); }), floatingActionButtonLocation: FloatingActionButtonLocation.startTop, floatingActionButton: FloatingActionButton( diff --git a/lib/app/pages/setting_page.dart b/lib/app/pages/setting_page.dart index 588f823..a603e90 100644 --- a/lib/app/pages/setting_page.dart +++ b/lib/app/pages/setting_page.dart @@ -5,14 +5,7 @@ import 'package:parental_control/services/auth.dart'; import 'package:parental_control/theme/theme.dart'; class SettingsPage extends StatelessWidget { - SettingsPage( - {Key? key, - this.title, - this.name, - this.email, - this.context, - required this.auth}) - : super(key: key); + SettingsPage({Key? key, this.title, this.name, this.email, this.context, required this.auth}) : super(key: key); final BuildContext? context; final AuthBase auth; final String? title; @@ -87,13 +80,8 @@ class SettingsPage extends StatelessWidget { return Scaffold( appBar: AppBar( title: Text('Settings'), - actions: [ - IconButton( - onPressed: () => confirmSignOut(context, auth), - icon: Icon(Icons.logout)) - ], + actions: [IconButton(onPressed: () => confirmSignOut(context, auth), icon: Icon(Icons.logout))], ), - backgroundColor: Theme.of(context).backgroundColor, body: Stack( children: [ Padding( @@ -169,6 +157,7 @@ class ProfileListItem extends StatelessWidget { Icon( LineAwesomeIcons.alternate_arrow_circle_right, size: 25, + color: CustomColors.greenPrimary, ), ], ), diff --git a/lib/app/splash/splash_content.dart b/lib/app/splash/splash_content.dart index 77caafb..c69cb76 100644 --- a/lib/app/splash/splash_content.dart +++ b/lib/app/splash/splash_content.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:parental_control/common_widgets/autosize_text.dart'; import 'package:parental_control/common_widgets/size_config.dart'; +import 'package:parental_control/theme/theme.dart'; class SplashContent extends StatelessWidget { const SplashContent({ @@ -22,31 +24,31 @@ class SplashContent extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - "Time's Up", + DisplayText( + text: "Time's Up", + fontSize: 35, style: TextStyle( - fontSize: getProportionateScreenWidth(25), - color: Colors.indigo.shade400, + color: CustomColors.indigoDark, fontWeight: FontWeight.w800, ), ), SizedBox(height: 8), - Text( - text, - style: TextStyle( - color: Colors.black.withOpacity(0.35), - fontSize: 11, - fontWeight: FontWeight.w500, - height: 1.5), - textAlign: TextAlign.left, + Container( + width: MediaQuery.of(context).size.width / 1.5, + child: DisplayText( + text: text, + style: TextStyle( + color: Colors.black.withOpacity(0.5), + fontWeight: FontWeight.w500, + height: 1.5), + ), ), ], ), ), - SizedBox(height: 8), Image.asset( image, - height: getProportionateScreenHeight(220), + height: getProportionateScreenHeight(150), width: getProportionateScreenWidth(135), ), ], diff --git a/lib/app/splash/splash_screen.dart b/lib/app/splash/splash_screen.dart index 8d66676..a8c87e7 100644 --- a/lib/app/splash/splash_screen.dart +++ b/lib/app/splash/splash_screen.dart @@ -58,6 +58,7 @@ class _SplashScreenState extends State { Expanded( flex: 3, child: PageView.builder( + physics: BouncingScrollPhysics(), onPageChanged: (value) { setState(() { currentPage = value; @@ -114,7 +115,7 @@ class _SplashScreenState extends State { style: ButtonStyle( backgroundColor: MaterialStateProperty.all( - Theme.of(context).primaryColor)), + CustomColors.greenPrimary)), onPressed: () { SharedPreference().setVisitingFlag(); SharedPreference().setChildDevice(); diff --git a/lib/common_widgets/autosize_text.dart b/lib/common_widgets/autosize_text.dart new file mode 100644 index 0000000..1555542 --- /dev/null +++ b/lib/common_widgets/autosize_text.dart @@ -0,0 +1,23 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/material.dart'; + +class DisplayText extends StatelessWidget { + final String text; + final TextStyle style; + final double? fontSize; + + const DisplayText( + {Key? key, required this.text, required this.style, this.fontSize}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return AutoSizeText( + text, + style: style, + maxLines: 10, + minFontSize: fontSize ?? 10, + maxFontSize: fontSize ?? 21, + ); + } +} diff --git a/lib/common_widgets/child_horizontal_view.dart b/lib/common_widgets/child_horizontal_view.dart index 45c0052..6ccfef6 100644 --- a/lib/common_widgets/child_horizontal_view.dart +++ b/lib/common_widgets/child_horizontal_view.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:parental_control/theme/theme.dart'; class Kids extends StatelessWidget { final String? image_location; @@ -13,9 +14,10 @@ class Kids extends StatelessWidget { onTap: onPressed, child: image_location != null || image_caption != null ? Container( - padding: const EdgeInsets.symmetric(horizontal: 18), - height: 200, - width: 150.0, + margin: EdgeInsets.symmetric(vertical: 10), + padding: const EdgeInsets.symmetric(horizontal: 4), + height: 130, + width: 130.0, child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -34,8 +36,8 @@ class Kids extends StatelessWidget { child: Text( image_caption!, style: TextStyle( - color: Colors.black45, - fontSize: 16, + color: CustomColors.indigoLight, + fontSize: 17, fontWeight: FontWeight.w700), ), ), diff --git a/lib/common_widgets/feature_widget.dart b/lib/common_widgets/feature_widget.dart new file mode 100644 index 0000000..4baecbc --- /dev/null +++ b/lib/common_widgets/feature_widget.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; +import 'package:parental_control/theme/theme.dart'; + +class FeatureWidget extends StatelessWidget { + final String? title; + final Widget? child; + final IconData? icon; + + const FeatureWidget({Key? key, this.title, this.icon, this.child}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + height: MediaQuery.of(context).size.height * 0.07, + decoration: BoxDecoration( + color: CustomColors.indigoDark, + borderRadius: BorderRadius.all(Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: CustomColors.indigoPrimary.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + padding: EdgeInsets.all(15.0), + margin: EdgeInsets.symmetric(horizontal: 85.0, vertical: 30), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox(width: 10), + if (child != null) child ?? SizedBox.shrink(), + title != null + ? Text( + title!, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w800, + color: CustomColors.indigoLight), + ) + : SizedBox.shrink(), + Spacer(), + if (icon != null) + Icon( + icon, + size: 22, + ), + SizedBox.shrink(), + ], + ), + ); + } +} diff --git a/lib/common_widgets/form_submit_button.dart b/lib/common_widgets/form_submit_button.dart index 06d01b0..2e68c6a 100644 --- a/lib/common_widgets/form_submit_button.dart +++ b/lib/common_widgets/form_submit_button.dart @@ -1,14 +1,16 @@ import 'package:flutter/material.dart'; +import 'package:parental_control/theme/theme.dart'; import 'custom_raised_button.dart'; class FormSubmitButton extends CustomRaisedButton { - FormSubmitButton({required String text, required VoidCallback onPressed}) + FormSubmitButton( + {required String text, required VoidCallback onPressed, Color? color}) : super( child: Text(text, style: TextStyle(color: Colors.white, fontSize: 20)), height: 44.0, - color: Colors.indigo, + color: color ?? CustomColors.indigoDark, borderRadius: 4.0, - onPressed: () => onPressed); + onPressed: onPressed); } diff --git a/lib/common_widgets/loading_map.dart b/lib/common_widgets/loading_map.dart new file mode 100644 index 0000000..bd1c3c6 --- /dev/null +++ b/lib/common_widgets/loading_map.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class LoadingMap extends StatelessWidget { + const LoadingMap({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + height: 250, + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(16)), + color: Colors.black.withOpacity(0.14)), + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index 9fc8791..114b7eb 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -45,8 +45,7 @@ class _MyAppState extends State { debugShowCheckedModeBanner: false, title: 'Parental Control', theme: AppTheme.lightTheme, - darkTheme: AppTheme.DarkTheme, - themeMode: ThemeMode.system, + darkTheme: AppTheme.darkTheme, home: FutureBuilder( future: Future.wait([ geoService.getInitialLocation(), diff --git a/lib/sign_in/email_sign_in_form_bloc_based.dart b/lib/sign_in/email_sign_in_form_bloc_based.dart index 1e415a2..b006f11 100644 --- a/lib/sign_in/email_sign_in_form_bloc_based.dart +++ b/lib/sign_in/email_sign_in_form_bloc_based.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:parental_control/common_widgets/form_submit_button.dart'; import 'package:parental_control/common_widgets/show_exeption_alert.dart'; import 'package:parental_control/services/auth.dart'; +import 'package:parental_control/theme/theme.dart'; import 'package:provider/provider.dart'; import 'email_sign_in_bloc.dart'; @@ -24,7 +25,6 @@ class EmailSignInFormBlocBased extends StatefulWidget { ); } - ///_____________________________________________________________________________________ @override _EmailSignInFormBlocBasedState createState() => _EmailSignInFormBlocBasedState(); @@ -138,6 +138,7 @@ class _EmailSignInFormBlocBasedState extends State { onPressed: () => model.canSubmitRegister || model.canSubmitSignIn ? _submit(model) : null, + color: CustomColors.greenPrimary, text: model.primaryButtonText, ), SizedBox(height: 8.0), @@ -148,8 +149,6 @@ class _EmailSignInFormBlocBasedState extends State { ]; } - ///------------------------------ Widgets ------------------------------------------------- - Widget _buildEmailTextField(EmailSignInModel model) { return TextField( focusNode: _emailFocusNode, diff --git a/lib/sign_in/sign_in_button.dart b/lib/sign_in/sign_in_button.dart index 7354d91..c19a91e 100644 --- a/lib/sign_in/sign_in_button.dart +++ b/lib/sign_in/sign_in_button.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:parental_control/common_widgets/custom_raised_button.dart'; +import 'package:parental_control/theme/theme.dart'; class SignInButton extends CustomRaisedButton { SignInButton( @@ -13,6 +14,6 @@ class SignInButton extends CustomRaisedButton { text, style: TextStyle(color: textColor, fontSize: 15.0), ), - color: color ?? Colors.indigo, + color: color ?? CustomColors.indigoLight, onPressed: onPressed ?? () {}); } diff --git a/lib/sign_in/sign_in_page.dart b/lib/sign_in/sign_in_page.dart index 7070967..480cc98 100644 --- a/lib/sign_in/sign_in_page.dart +++ b/lib/sign_in/sign_in_page.dart @@ -6,6 +6,7 @@ import 'package:parental_control/services/auth.dart'; import 'package:parental_control/sign_in/sign_in_button.dart'; import 'package:parental_control/sign_in/sign_in_manager.dart'; import 'package:parental_control/sign_in/social_sign_in_button.dart'; +import 'package:parental_control/theme/theme.dart'; import 'package:provider/provider.dart'; import 'email_sign_in_page.dart'; @@ -98,7 +99,7 @@ class SignInPage extends StatelessWidget { Widget _buildContent(BuildContext context) { return Container( - decoration: BoxDecoration(color: Theme.of(context).backgroundColor), + decoration: BoxDecoration(color: CustomColors.indigoLight), child: Padding( padding: EdgeInsets.all(16.0), child: Column( diff --git a/lib/theme/theme.dart b/lib/theme/theme.dart index 4f7c333..9870058 100644 --- a/lib/theme/theme.dart +++ b/lib/theme/theme.dart @@ -1,33 +1,54 @@ import 'package:flutter/material.dart'; +class CustomColors { + static Color indigoPrimary = Color(0xFF283593); + static Color indigoDark = Color(0xFF1a237e); + static Color greenPrimary = Color(0xFF00C853); + static Color indigoLight = Color(0xFF9fa8da); +} + +class CustomDecoration { + static BoxDecoration withShadowDecoration = BoxDecoration( + color: CustomColors.indigoDark, + borderRadius: BorderRadius.all(Radius.circular(10)), + boxShadow: [ + BoxShadow( + color: CustomColors.indigoPrimary.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ); +} class AppTheme { const AppTheme(); static ThemeData lightTheme = ThemeData( - backgroundColor: Colors.white, - primarySwatch: Colors.indigo, - brightness: Brightness.light, - cardTheme: CardTheme(color: Colors.white), - textTheme: TextTheme(headline4: TextStyle(color: Colors.indigo)), - iconTheme: IconThemeData(color: Colors.indigo), - floatingActionButtonTheme: - FloatingActionButtonThemeData(backgroundColor: Colors.indigo), - bottomAppBarColor: Colors.indigo, - dividerColor: Colors.indigo, - primaryTextTheme: TextTheme(bodyText2: TextStyle(color: Colors.black))); - - static ThemeData DarkTheme = ThemeData( - backgroundColor: Colors.black, - primarySwatch: Colors.indigo, - brightness: Brightness.light, - cardTheme: CardTheme(color: Colors.white), - textTheme: TextTheme(headline4: TextStyle(color: Colors.indigo)), - iconTheme: IconThemeData(color: Colors.white), - floatingActionButtonTheme: - FloatingActionButtonThemeData(backgroundColor: Colors.indigo), - bottomAppBarColor: Colors.white, - dividerColor: Colors.grey.shade200, - primaryTextTheme: TextTheme(bodyText2: TextStyle(color: Colors.white))); + primarySwatch: buildMaterialColor(CustomColors.indigoDark), + primaryColor: CustomColors.indigoDark, + scaffoldBackgroundColor: Colors.white, + appBarTheme: AppBarTheme(backgroundColor: CustomColors.indigoDark), + brightness: Brightness.light, + cardTheme: CardTheme(color: Colors.white), + iconTheme: IconThemeData(color: Colors.indigo), + dividerColor: CustomColors.indigoDark, + floatingActionButtonTheme: FloatingActionButtonThemeData( + backgroundColor: CustomColors.greenPrimary, + foregroundColor: Colors.white), + ); + + static ThemeData darkTheme = ThemeData( + primarySwatch: buildMaterialColor(CustomColors.indigoDark), + primaryColor: CustomColors.indigoDark, + scaffoldBackgroundColor: Colors.white, + appBarTheme: AppBarTheme(backgroundColor: CustomColors.indigoDark), + brightness: Brightness.light, + cardTheme: CardTheme(color: Colors.white), + iconTheme: IconThemeData(color: CustomColors.indigoLight), + floatingActionButtonTheme: FloatingActionButtonThemeData( + backgroundColor: CustomColors.indigoLight), + ); static TextStyle h1Style = const TextStyle(fontSize: 24, fontWeight: FontWeight.bold); @@ -38,7 +59,6 @@ class AppTheme { static TextStyle h6Style = const TextStyle(fontSize: 14); } - extension PaddingHelper on Widget { Padding get p16 => Padding(padding: EdgeInsets.all(16), child: this); Padding get p8 => Padding(padding: EdgeInsets.only(top: 8), child: this); @@ -49,9 +69,12 @@ extension PaddingHelper on Widget { Padding(padding: EdgeInsets.all(value), child: this); /// Horizontal Padding 16 - Padding get hP4 => Padding(padding: EdgeInsets.symmetric(horizontal: 4), child: this); - Padding get hP8 => Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: this); - Padding get hP16 => Padding(padding: EdgeInsets.symmetric(horizontal: 16), child: this); + Padding get hP4 => + Padding(padding: EdgeInsets.symmetric(horizontal: 4), child: this); + Padding get hP8 => + Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: this); + Padding get hP16 => + Padding(padding: EdgeInsets.symmetric(horizontal: 16), child: this); /// Vertical Padding 16 Padding get vP16 => @@ -79,20 +102,50 @@ class FontSizes { } class TextStyles { - static TextStyle get title =>TextStyle(fontSize: FontSizes.title); - static TextStyle get titleM =>TextStyle(fontSize: FontSizes.titleM); - static TextStyle get titleSize15 => title.copyWith(fontWeight: FontWeight.w500,fontSize: 15); - static TextStyle get titleNormal => title.copyWith(fontWeight: FontWeight.w500,fontSize: FontSizes.titleSmall); - static TextStyle get titleMedium => titleM.copyWith(fontWeight: FontWeight.w300); - static TextStyle get h1Style => TextStyle(fontSize: FontSizes.sizeXXl, fontWeight: FontWeight.bold); - static TextStyle get h2Style => TextStyle(fontSize: FontSizes.sizeXl, fontWeight: FontWeight.bold,color: Colors.black); - static TextStyle get h3Large => TextStyle(fontSize: FontSizes.Large, fontWeight: FontWeight.bold,color: Colors.black); - static TextStyle get headTitleColored=> TextStyle(fontSize: FontSizes.sizeXl, fontWeight: FontWeight.bold,color: Colors.blueAccent); - static TextStyle get body => TextStyle(fontSize: FontSizes.body, fontWeight: FontWeight.w300); + static TextStyle get title => TextStyle(fontSize: FontSizes.title); + static TextStyle get titleM => TextStyle(fontSize: FontSizes.titleM); + static TextStyle get titleSize15 => + title.copyWith(fontWeight: FontWeight.w500, fontSize: 15); + static TextStyle get titleNormal => title.copyWith( + fontWeight: FontWeight.w500, fontSize: FontSizes.titleSmall); + static TextStyle get titleMedium => + titleM.copyWith(fontWeight: FontWeight.w300); + static TextStyle get h1Style => + TextStyle(fontSize: FontSizes.sizeXXl, fontWeight: FontWeight.bold); + static TextStyle get h2Style => TextStyle( + fontSize: FontSizes.sizeXl, + fontWeight: FontWeight.bold, + color: Colors.black); + static TextStyle get h3Large => TextStyle( + fontSize: FontSizes.Large, + fontWeight: FontWeight.bold, + color: Colors.black); + static TextStyle get headTitleColored => TextStyle( + fontSize: FontSizes.sizeXl, + fontWeight: FontWeight.bold, + color: Colors.blueAccent); + static TextStyle get body => + TextStyle(fontSize: FontSizes.body, fontWeight: FontWeight.w300); static TextStyle get bodySm => body.copyWith(fontSize: FontSizes.bodySm); } - - - - +// This Function creates a material color from HEX color value +MaterialColor buildMaterialColor(Color color) { + List strengths = [.05]; + Map swatch = {}; + final int r = color.red, g = color.green, b = color.blue; + + for (int i = 1; i < 10; i++) { + strengths.add(0.1 * i); + } + strengths.forEach((strength) { + final double ds = 0.5 - strength; + swatch[(strength * 1000).round()] = Color.fromRGBO( + r + ((ds < 0 ? r : (255 - r)) * ds).round(), + g + ((ds < 0 ? g : (255 - g)) * ds).round(), + b + ((ds < 0 ? b : (255 - b)) * ds).round(), + 1, + ); + }); + return MaterialColor(color.value, swatch); +} diff --git a/pubspec.lock b/pubspec.lock index d818dc4..27fa0e0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,6 +49,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.10.0" + auto_size_text: + dependency: "direct main" + description: + name: auto_size_text + sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599" + url: "https://pub.dev" + source: hosted + version: "3.0.0" bloc: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index db698e3..aa69e58 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -48,6 +48,7 @@ dependencies: flutter_bloc: ^8.0.1 mockito: ^5.0.0 flutter_local_notifications: ^14.0.0-dev.2 + auto_size_text: ^3.0.0 test: any