From f5a6a1cc6bc332b1fe9de630675659286daf0d48 Mon Sep 17 00:00:00 2001 From: netharu methmitha Date: Thu, 14 Apr 2022 17:58:20 +0530 Subject: [PATCH] init --- .gitignore | 46 ++ .metadata | 10 + .vscode/launch.json | 25 + README.md | 16 + analysis_options.yaml | 29 ++ android/.gitignore | 13 + android/app/build.gradle | 68 +++ android/app/src/debug/AndroidManifest.xml | 10 + android/app/src/main/AndroidManifest.xml | 38 ++ .../com/example/whatskit/MainActivity.kt | 5 + .../res/drawable-v21/launch_background.xml | 12 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 4672 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 3183 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 6040 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 8656 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10984 bytes .../app/src/main/res/values-night/styles.xml | 18 + android/app/src/main/res/values/styles.xml | 18 + android/app/src/profile/AndroidManifest.xml | 10 + android/build.gradle | 31 ++ android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 6 + android/settings.gradle | 11 + assets/icon.png | Bin 0 -> 20728 bytes lib/main.dart | 41 ++ lib/pages/preview_page.dart | 263 ++++++++++ lib/pages/statuses_page.dart | 99 ++++ lib/widgets/status_card.dart | 115 +++++ pubspec.lock | 460 ++++++++++++++++++ pubspec.yaml | 98 ++++ 31 files changed, 1457 insertions(+) create mode 100644 .gitignore create mode 100644 .metadata create mode 100644 .vscode/launch.json create mode 100644 README.md create mode 100644 analysis_options.yaml create mode 100644 android/.gitignore create mode 100644 android/app/build.gradle create mode 100644 android/app/src/debug/AndroidManifest.xml create mode 100644 android/app/src/main/AndroidManifest.xml create mode 100644 android/app/src/main/kotlin/com/example/whatskit/MainActivity.kt create mode 100644 android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 android/app/src/main/res/drawable/launch_background.xml create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/values-night/styles.xml create mode 100644 android/app/src/main/res/values/styles.xml create mode 100644 android/app/src/profile/AndroidManifest.xml create mode 100644 android/build.gradle create mode 100644 android/gradle.properties create mode 100644 android/gradle/wrapper/gradle-wrapper.properties create mode 100644 android/settings.gradle create mode 100644 assets/icon.png create mode 100644 lib/main.dart create mode 100644 lib/pages/preview_page.dart create mode 100644 lib/pages/statuses_page.dart create mode 100644 lib/widgets/status_card.dart create mode 100644 pubspec.lock create mode 100644 pubspec.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0fa6b67 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.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. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..166a998 --- /dev/null +++ b/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: c860cba910319332564e1e9d470a17074c1f2dfd + channel: stable + +project_type: app diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..7b38701 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "whatskit", + "request": "launch", + "type": "dart" + }, + { + "name": "whatskit (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "whatskit (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..ef7e1d0 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# whatskit + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +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. diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..61b6c4d --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,29 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..6f56801 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,13 @@ +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 +**/*.keystore +**/*.jks diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..885e260 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,68 @@ +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') +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 from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion flutter.compileSdkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.netharuM.whatskit" + minSdkVersion 16 + targetSdkVersion 30 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..a420917 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a8d8672 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/example/whatskit/MainActivity.kt b/android/app/src/main/kotlin/com/example/whatskit/MainActivity.kt new file mode 100644 index 0000000..45b1a76 --- /dev/null +++ b/android/app/src/main/kotlin/com/example/whatskit/MainActivity.kt @@ -0,0 +1,5 @@ +package com.netharuM.whatskit + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() {} diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + 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..304732f --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + 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 0000000000000000000000000000000000000000..c754479a6608f1ddedc7fad1b8dfe12900211445 GIT binary patch literal 4672 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 VFr!(fsl)&P002ovPDHLkV1hOe56%Dp literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f5a7a83efaf1aa2321b3684f298f3379ac7c59d1 GIT binary patch literal 6040 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

; zvj7TIDm?6|brI#;ER{kFR?_ztmo^W)%5ZT0k_Y~zWXr9thxA*kKlTf!P7m2ECA0w6 zficF(nEO`j$N&!t4_sYX(M{|E6ywFdGRJeKK<3sk;~0)&uQ4KRzGRo+GK`b<5#{Pr zPxY@esicn)DbuN(Zv1W3OgxSQqdi{{9Phh>_bGqiCM$Q>|3Ksw6KD>@9Rn7XUX}xq z*lR4Tk$ziem5&B9PFi_YI6=A_V|q-r};r~(Qf53(t~ zR;Cph@Q|nOL-ST_*D>933lp$-^r?H6uZcvkszRoW?;R zD(Jw1FyJH}H>3!Y^-t)bQa4N;JG}SOq*{vM%#*L9lR=h`Wvae$gU zddZQ82E&Uz4O{+kZ`dwp2VSsV$?2@$`X84)q@+GypG&J7YKt05II0M98k`36Vl44i#P^e3y}t_4v*076I*N-%}d?Sj8Hy z%@J!6Y=oLwtpQnb$)#~vlN#r|{?j>-zY|u8+1{L;JZmU-9{M8ffiW9NJ)uEwTojlh9~P`2qb$AUZ(}rW1BC5>;IAc%oi(#8A%`CHY44i zAZj@nQtuVO;rLcZQzWNo;NH39<>E@BoQhvgo9YWYa0)@8NA_f|-^C{{0~3pfU&M?r zj=*ise%xIYka=+Z6xkwnLGS^3iXqq+BEu%l!;q{F30xSB=f!9z;dt_U_j`>*`lL-f ze9>eCC`-V&guC{_c*Qz5@Lg^gm#irP4Otcyt5XF~<@`fD@kK=EUrjv|QD@1NF~WcMs|S1subokRSc{Yc2deA8q{s! zihnr03`k^LPEb*Z{pnvdu<^9YUl(w4sqtUQ;iEM69joXCE@6*bAhv~{?2A6;PUKr8yULKJiFrr#L9`sYPum=T zf?n?a(R-FRr6ld`$<37m#+~0clmU%CA}%YLI*B;GI`j9M#u6y4kmja|gb_pYR?D_1ni;)*{;|FHu7i2m+TpBtwL zvmmP0*)rdDM3asr8x_(MKZUmaA%+aEwS^B0VrE-_7-e$E@Z5trIV ztK-eN418jqI-~Dzc6_?={EVxS00Cfn{T!5gE_1oR5#j!gJ(y?CHi(aJuygJtf3)R2 zVOWu+Wrg^mqsRIZe~cq{HnaWH7^|gSWVC7B6J%@d!-vexf4Ps?DgZ|gRr5Psx&xTw z^=uR;`ZO*zM1%~r(Zp|_<6HK_A2fE85VvvsmfPQ3P)doWmSEd@0}Vu-?aF3mZCHfw zDbgHDTyv4JK+5w@?(W~q!-2I>QoKy(8(+vJ$y@c52v>D9LB0&ub^e3)rHrxTOq0O{ z`S%u%$6ulVlzVMU7la5V{#WVUaU)X98q0_7BjIs8r)xYcP@^!9g}2nVQI7_|(a;CL z!@_VWfIS2GwINe5)ZlG|wejLO?Q^g%O??0tlVa@oAjIeTiLgch%MgJEGXuPtx`6Q< zz=`nnnkSsf{MM=tq5i6`(qHXb!Vxn}Kd?VElVCf+wHmT3#vKV+5~x*H#@k{qYc)Vc zZWBYoH@Jd?f3u?v*2Bwb-SK4a`1GccS;F`|_9V$Z(N7C=V+x5-d4HjIZ*ju;`Vn{y zj%DD$%9RNvoStpj6qre{QyX2#c~(-ws!cQ4D~5PnpxE_;4vXIPg*9?|Zw%^9KMOvM z%hYv0=FIeQYx|{n`m8(j2;Ch-YXaMCu{ZEpaUr(BcgM1pQDd{y-PA@A3FvIR%7hx3 zo;Z8EQ2WVig@U+|ZOuMy_8`hP^aK8d;7gwh%4+r}6zGw> zz$`T$a=75njYGAhdwRr=6Y@pwU)Xt7D23+=-_Y;;l=6H&0M88&;?G|4jTU{QZ+aj4 znoY?&rU++Xie&VhcXlaj4f`zjRX7>@eB6dJ58Ka*X-L-|6^BWa`=PXYoR|nurtzTn zZoKKT6c|nZb8t!a|18d~yk_^1rQKEJFDG-HUZ$Ofz(a5zV%W z4h3nudm-~{FW4gHBS1Z#uxg1x`!{C^Xb*WISxsT3#%dgYPX(;F)p3e&KO=`8tP*Va zE}L+&_#$K!3qRxed|F@PMpXS6?rj98YRoS2Cce;Qt_Vc)0^70ZgDn7G0t#j-J{+Ltk~Xb%WM*8xX4hZgWKsx5-vMJ_e?zzbibKCr62St! ze3ND$wFn2U>vZ25)@x{fCkYd?;3v?U@%>dlUmliUX4O(bEA_G;T3q-Tm;a8kxmf1s zlJ$&?H213z1SU|s*){k)FFl(Zz9S{GYfW}$w=G}b{Ci+MkdvAzW1C+~p6wLY?-&@q z2>nIex~sJpfbWDrC1NKsWVaVUwVC3m?&-&%@+Kn+t)nALy{XtJ3MLIBQ}DuG`1aPA zRd#cwUL-id^DKb)m(zj#crX0)`^Zv@3#+3yaVziQni%8!ZC1br-RA#u{K{Pp#c&IF zdU%X`bB!DgJ$(_{E z2J1f_Zh<)2d}CJEIG6`+YC57ri-GRxkI)Eb$MeH|g_L#f=4xluHpF}CD1hm{k#b}x zNN($eibue5o5|OmZS|wmS=$BsS3co$Y*_%#cTzoj)QzJTzeLo_JWyq~>|{RK;q{jt zK_(k)H`L_tf$pKfDf9w9_d}?b7wLAmz}s87VI8uQT%zQJmk808D#K6A+mqN-vuebD zhUeXs?mi#F@_0bJy!?oggXRTNabJCaw0u}5OZRUBR4%>{U%meQBV)f!!fFgO^ zC^)VdNN+u+H^Hs$$!&hoNIW;PQ#Wv|;Im#4I{Nx1eqDyN0Tks(`o58tFn0M@3(pet z4o$G0q7c**V^dKN0W@X~?c430w}~Ei^S0 zsEG>4Jw=E2)V6LOM^-UV1yK{;_tJO*iw?357zZO9`VbccU-!ZaMzhyA0L25BdiIC2 zuUzGLt915^(d>Sb+R(XpVyyplUEsa{T7|cEIA9pNjQ`pFRzk(e!4aVq*uM7?q4{)2 zt!Ck_!&RORcfF4r2AQ3F4tsykIMFODEwg1kS9p*45q- zq*J%RDZCq(1!@g=kTiGyT{>H7%IqTe&WDYeVsEYsc#7{g06HkkvR^JU-b7q%`%~MO zUP@X^E<~?8+FE#?_e(wm0DjN87*e{(o3SDvE+}@ zrmM#~;}xZc{To&g1!k-L>G8cUty%mBGA|HBAEi(e4)~6F0fEpVz0hF^LL6-D?ke(o zzzy-Lx(-JIB3eQ82V%ZM{^*O*lYf75^7Gdjw%_#Dw&9`^0@>DGK?(^+Yz5|r?_;ga zDtmm?OesZnzU!kUd=zjGhr5J6AlWhREfyXh-#}EqUk|=M>l|U9sx{8iv<&qn%Z+1* zPYK_g5*daLXZu-%T#^`7fi#8yn%Xe32QIAi3`aqBWY z*UB^tuwUVQ@mTBtNpnSE$iQ3oKHTYmdIIKnK!K0T_f0_RBumuqv)>#%es-)}^DZ7j zcc<+Hwa*Y&4OfEM@d&5%1`JlnSeIflpe3Jqv2XHC;YHF6r~2n$&KHpt^vVoTtPpMt zY=-|#U%^k_r=-rQUM_4ED?{P5>G6FPOG@eW*E;m*yax52)-@Xp-Dn-LUO@KAX>YZ!UP}xww8{FhC`GnYW jRa3Z_bF2S%c)^@<>v6ASBI|l%>lhAp!pb6nE^U literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..3db14bb --- /dev/null +++ b/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + 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..d460d1e --- /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..a420917 --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..4256f91 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.6.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.1.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +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..94adc3a --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..bc6a58a --- /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-6.7-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/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..977e71fc533f52dcebbeeb48272e4bed62388f1b GIT binary patch literal 20728 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 Kvb)aCFZsWkkMuwQ literal 0 HcmV?d00001 diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..472cdaa --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:whatskit/pages/statuses_page.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: generateMaterialColorFromColor(const Color(0xff00a884)), + scaffoldBackgroundColor: const Color(0xff111b21), + cardColor: const Color(0xff202c33), + primaryColor: const Color(0xff00a884), + textTheme: Theme.of(context).textTheme.apply(bodyColor: Colors.white), + iconTheme: Theme.of(context).iconTheme.copyWith(color: Colors.white), + ), + home: const StatusesPage(), + ); + } +} + +MaterialColor generateMaterialColorFromColor(Color color) { + return MaterialColor(color.value, { + 50: Color.fromRGBO(color.red, color.green, color.blue, 0.1), + 100: Color.fromRGBO(color.red, color.green, color.blue, 0.2), + 200: Color.fromRGBO(color.red, color.green, color.blue, 0.3), + 300: Color.fromRGBO(color.red, color.green, color.blue, 0.4), + 400: Color.fromRGBO(color.red, color.green, color.blue, 0.5), + 500: Color.fromRGBO(color.red, color.green, color.blue, 0.6), + 600: Color.fromRGBO(color.red, color.green, color.blue, 0.7), + 700: Color.fromRGBO(color.red, color.green, color.blue, 0.8), + 800: Color.fromRGBO(color.red, color.green, color.blue, 0.9), + 900: Color.fromRGBO(color.red, color.green, color.blue, 1.0), + }); +} diff --git a/lib/pages/preview_page.dart b/lib/pages/preview_page.dart new file mode 100644 index 0000000..4ac2eb0 --- /dev/null +++ b/lib/pages/preview_page.dart @@ -0,0 +1,263 @@ +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:video_player/video_player.dart'; +import 'package:share_plus/share_plus.dart'; +import 'package:filesystem_picker/filesystem_picker.dart'; + +class PreviewPage extends StatefulWidget { + final File file; + const PreviewPage({Key? key, required this.file}) : super(key: key); + + @override + State createState() => _PreviewPageState(); +} + +class _PreviewPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: SafeArea( + child: Builder( + builder: (context) { + if (widget.file.path.endsWith('.mp4')) { + return Column( + children: [ + StatusPlayer( + file: widget.file, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + TextButton( + onPressed: () { + Share.shareFiles( + [widget.file.path], + ); + }, + child: const Icon(Icons.share), + ), + TextButton( + onPressed: () async { + String? path = await FilesystemPicker.open( + title: 'Save to folder', + context: context, + rootDirectory: Directory( + '/storage/emulated/0/', + ), + fsType: FilesystemType.folder, + pickText: 'Save file to this folder', + folderIconColor: Colors.teal, + ); + if (path != null) { + await widget.file.copy( + '$path/${widget.file.path.split('/').last}'); + } + }, + child: const Icon(Icons.download), + ), + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Icon(Icons.cancel), + ), + ], + ) + ], + ); + } else if (widget.file.path.endsWith('.jpg')) { + return Stack( + children: [ + Center( + child: Image.file( + File(widget.file.path), + width: double.infinity, + ), + ), + Column( + children: [ + Expanded( + child: Container(), + ), + Container( + color: Colors.black.withOpacity(0.7), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + TextButton( + onPressed: () { + Share.shareFiles( + [widget.file.path], + ); + }, + child: const Icon(Icons.share), + ), + TextButton( + onPressed: () async { + String? path = await FilesystemPicker.open( + title: 'Save to folder', + context: context, + rootDirectory: Directory( + '/storage/emulated/0/', + ), + fsType: FilesystemType.folder, + pickText: 'Save file to this folder', + folderIconColor: Colors.teal, + ); + if (path != null) { + await widget.file.copy( + '$path/${widget.file.path.split('/').last}'); + } + }, + child: const Icon(Icons.download), + ), + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Icon(Icons.cancel), + ), + ], + ), + ), + ], + ) + ], + ); + } else { + return const Center(child: Text('Unknown file type')); + } + }, + ), + ), + ); + } +} + +class StatusPlayer extends StatefulWidget { + final File file; + const StatusPlayer({Key? key, required this.file}) : super(key: key); + + @override + State createState() => _StatusPlayerState(); +} + +class _StatusPlayerState extends State { + late VideoPlayerController? _controller; + + @override + void initState() { + super.initState(); + _controller = VideoPlayerController.file(File(widget.file.path)); + _controller!.initialize().then((_) { + _controller!.play(); + setState(() {}); + }); + super.initState(); + } + + @override + void dispose() { + _controller?.pause(); + _controller?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Expanded( + child: Stack( + children: [ + Center( + child: _controller != null + ? AspectRatio( + aspectRatio: _controller!.value.aspectRatio, + child: VideoPlayer(_controller!), + ) + : const CircularProgressIndicator(), + ), + Column( + children: [ + Expanded(child: Container()), + Container( + height: 50, + margin: const EdgeInsets.all(12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Colors.black.withOpacity(0.5), + ), + child: Row( + children: [ + IconButton( + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + color: Theme.of(context).primaryColor, + onPressed: () { + setState(() { + _controller!.value.isPlaying + ? _controller!.pause() + : _controller!.play(); + }); + }, + icon: _controller!.value.isPlaying + ? const Icon(Icons.pause) + : const Icon(Icons.play_arrow), + ), + PlayerPosIndicator(controller: _controller!), + ], + ), + ), + ], + ), + ], + ), + ); + } +} + +class PlayerPosIndicator extends StatefulWidget { + final VideoPlayerController controller; + const PlayerPosIndicator({Key? key, required this.controller}) + : super(key: key); + + @override + State createState() => _PlayerPosIndicatorState(); +} + +class _PlayerPosIndicatorState extends State { + double position = 0; + + void _update() { + setState(() { + position = widget.controller.value.position.inMilliseconds.toDouble(); + }); + } + + @override + void initState() { + position = widget.controller.value.position.inMilliseconds.toDouble(); + widget.controller.addListener(_update); + super.initState(); + } + + @override + void dispose() { + widget.controller.removeListener(_update); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Expanded( + child: Slider( + value: position, + min: 0, + max: widget.controller.value.duration.inMilliseconds.toDouble(), + onChanged: (double value) { + widget.controller.seekTo(Duration(milliseconds: value.toInt())); + }, + ), + ); + } +} diff --git a/lib/pages/statuses_page.dart b/lib/pages/statuses_page.dart new file mode 100644 index 0000000..4dd6a8d --- /dev/null +++ b/lib/pages/statuses_page.dart @@ -0,0 +1,99 @@ +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:whatskit/widgets/status_card.dart'; + +class StatusesPage extends StatefulWidget { + const StatusesPage({Key? key}) : super(key: key); + + @override + State createState() => _StatusesPageState(); +} + +class _StatusesPageState extends State { + List _statusFiles = []; + + Future> getFileList() async { + final bool permissionStatus = + await Permission.manageExternalStorage.isGranted; + if (!permissionStatus) { + await Permission.manageExternalStorage.request(); + } + Directory dir = Directory( + '/storage/emulated/0/Android/media/com.whatsapp/Whatsapp/Media/.Statuses/'); + List fileList = await dir.list(recursive: false).toList(); + return fileList.where((element) { + return element.path.endsWith('.mp4') || element.path.endsWith('.jpg'); + }).toList(); + } + + @override + void initState() { + _init(); + super.initState(); + } + + Future _init() async { + List statusFiles = await getFileList(); + setState(() { + _statusFiles = statusFiles; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('whatsapp status'), + ), + body: RefreshIndicator( + onRefresh: _init, + child: GridView.count( + crossAxisCount: 2, + children: [ + for (int i = 0; i < _statusFiles.length; i++) + Padding( + padding: const EdgeInsets.all(8.0), + child: WhatsappStatusCard( + file: _statusFiles[i], + ), + ), + ], + ), + ), + drawer: Drawer( + backgroundColor: Colors.transparent, + child: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.only( + topRight: Radius.circular(12), + bottomRight: Radius.circular(12)), + color: Theme.of(context).scaffoldBackgroundColor, + ), + child: ListView( + children: [ + DrawerHeader( + child: Column( + children: [ + Image.asset( + 'assets/icon.png', + width: 100, + ), + Text( + 'whatskit', + style: Theme.of(context).textTheme.headline6, + ), + ], + ), + decoration: BoxDecoration( + color: Theme.of(context).primaryColor, + borderRadius: BorderRadius.circular(12), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/widgets/status_card.dart b/lib/widgets/status_card.dart new file mode 100644 index 0000000..b0ea7e3 --- /dev/null +++ b/lib/widgets/status_card.dart @@ -0,0 +1,115 @@ +import 'dart:io'; +import 'dart:typed_data'; +import 'package:video_thumbnail/video_thumbnail.dart'; +import 'package:flutter/material.dart'; +import 'package:whatskit/pages/preview_page.dart'; + +class WhatsappStatusCard extends StatelessWidget { + final FileSystemEntity file; + const WhatsappStatusCard({Key? key, required this.file}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.0), + color: Theme.of(context).cardColor, + ), + child: Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(12), + child: PreviewFile( + file: File(file.path), + ), + ), + Material( + color: Colors.transparent, + child: InkWell( + onTap: () async { + Navigator.push( + context, + MaterialPageRoute( + builder: (builder) => PreviewPage( + file: File(file.path), + ), + ), + ); + }, + borderRadius: BorderRadius.circular(12), + ), + ), + ], + ), + ); + } +} + +class PreviewFile extends StatelessWidget { + final File file; + const PreviewFile({Key? key, required this.file}) : super(key: key); + + @override + Widget build(BuildContext context) { + if (file.path.endsWith('.jpg')) { + return Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: Image.file( + File(file.path), + fit: BoxFit.cover, + width: double.infinity, + height: double.infinity, + ), + ), + ); + } else if (file.path.endsWith('.mp4')) { + return FutureBuilder( + future: VideoThumbnail.thumbnailData( + video: file.path, + imageFormat: ImageFormat.JPEG, + quality: 50, + ), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return Stack( + children: [ + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: Image.memory( + snapshot.data!, + fit: BoxFit.cover, + width: double.infinity, + height: double.infinity, + ), + ), + ), + Center( + child: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.5), + borderRadius: BorderRadius.circular(50), + ), + child: const Icon( + Icons.play_arrow, + color: Colors.white, + ), + ), + ), + ], + ); + } else { + return const Center(child: CircularProgressIndicator()); + } + }, + ); + } else { + return Text( + file.path, + style: const TextStyle(color: Colors.white), + ); + } + } +} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..df11810 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,460 @@ +# 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.3.0" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.8.2" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + collection: + dependency: transitive + description: + name: collection + 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" + csslib: + dependency: transitive + description: + name: csslib + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.1" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + filesystem_picker: + dependency: "direct main" + description: + name: filesystem_picker + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_launcher_icons: + dependency: "direct dev" + description: + name: flutter_launcher_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.2" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + html: + dependency: transitive + description: + name: html + url: "https://pub.dartlang.org" + source: hosted + version: "0.15.0" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.3" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.3" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + url: "https://pub.dartlang.org" + source: hosted + version: "9.2.0" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + url: "https://pub.dartlang.org" + source: hosted + version: "9.0.2+1" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + url: "https://pub.dartlang.org" + source: hosted + version: "9.0.4" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "3.7.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "4.4.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + share_plus: + dependency: "direct main" + description: + name: share_plus + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.4" + share_plus_linux: + dependency: transitive + description: + name: share_plus_linux + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + share_plus_macos: + dependency: transitive + description: + name: share_plus_macos + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + share_plus_platform_interface: + dependency: transitive + description: + name: share_plus_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + share_plus_web: + dependency: transitive + description: + name: share_plus_web + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + share_plus_windows: + dependency: transitive + description: + name: share_plus_windows + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.8" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + url_launcher: + dependency: transitive + description: + name: url_launcher + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.20" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.15" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.15" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + video_player: + dependency: "direct main" + description: + name: video_player + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + video_player_android: + dependency: transitive + description: + name: video_player_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.2" + video_player_avfoundation: + dependency: transitive + description: + name: video_player_avfoundation + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.1" + video_player_platform_interface: + dependency: transitive + description: + name: video_player_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.1" + video_player_web: + dependency: transitive + description: + name: video_player_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.7" + video_thumbnail: + dependency: "direct main" + description: + name: video_thumbnail + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.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.16.2 <3.0.0" + flutter: ">=2.10.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..7d485e8 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,98 @@ +name: whatskit +description: toolkit for whatsapp. + +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: "none" # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.16.2 <3.0.0" + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + permission_handler: ^9.2.0 + video_thumbnail: ^0.5.0 + video_player: ^2.3.0 + share_plus: ^4.0.4 + filesystem_picker: ^2.0.0 + +dev_dependencies: + flutter_test: + sdk: flutter + + # 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 + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^1.0.0 + flutter_launcher_icons: "^0.9.2" + +flutter_icons: + image_path: "assets/icon.png" + android: true + ios: false + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/icon.png + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages