From 9a749cf006b876af279c84dc185f7ae747f75f9b Mon Sep 17 00:00:00 2001 From: Kherel Date: Wed, 6 Jan 2021 18:35:57 +0100 Subject: [PATCH] update --- android/app/build.gradle | 2 +- android/app/src/main/AndroidManifest.xml | 8 +- .../main/res/mipmap-hdpi/launcher_icon.png | Bin 2727 -> 1227 bytes .../main/res/mipmap-mdpi/launcher_icon.png | Bin 1699 -> 885 bytes .../main/res/mipmap-xhdpi/launcher_icon.png | Bin 3706 -> 1579 bytes .../main/res/mipmap-xxhdpi/launcher_icon.png | Bin 5762 -> 2212 bytes .../main/res/mipmap-xxxhdpi/launcher_icon.png | Bin 7819 -> 2784 bytes assets/images/icon/logo.png | Bin 12412 -> 0 bytes assets/images/icon/logo_android.png | Bin 0 -> 3183 bytes assets/images/icon/logo_ios.png | Bin 0 -> 2988 bytes ios/Podfile.lock | 6 + .../Icon-App-1024x1024@1x.png | Bin 71252 -> 30242 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 670 -> 354 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1434 -> 608 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 2151 -> 906 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 992 -> 525 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 2122 -> 907 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 3271 -> 1336 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1434 -> 608 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 3053 -> 1201 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 4600 -> 1703 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 4600 -> 1703 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 7277 -> 2371 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 2852 -> 1188 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 6036 -> 2018 bytes .../Icon-App-83.5x83.5@2x.png | Bin 6717 -> 2266 bytes lib/config/bloc_config.dart | 23 +- lib/config/brand_colors.dart | 20 +- lib/config/brand_theme.dart | 6 +- lib/config/hive_config.dart | 53 ++ lib/config/text_themes.dart | 8 + lib/logic/api_maps/api_map.dart | 11 + lib/logic/api_maps/cloud_flare.dart | 127 ++++ lib/logic/api_maps/hetzner.dart | 64 ++ .../cubit/app_config/app_config_cubit.dart | 86 +++ .../cubit/app_config/app_config_state.dart | 76 +++ .../app_settings/app_settings_cubit.dart | 34 +- .../app_settings/app_settings_state.dart | 10 +- .../initializing/cloudflare_form_cubit.dart | 52 ++ .../forms/initializing/domain_form_cubit.dart | 60 ++ .../initializing/hetzner_form_cubit.dart | 40 +- .../forms/initializing/user_form_cubit.dart | 56 ++ lib/logic/cubit/forms/user/user.dart | 51 ++ .../cubit/forms/validations/validations.dart | 13 + .../initializing/initializing_cubit.dart | 30 - .../initializing/initializing_state.dart | 26 - lib/logic/cubit/users/users_cubit.dart | 37 +- lib/logic/cubit/users/users_state.dart | 2 + lib/logic/models/cloudflare_domain.dart | 19 + lib/logic/models/cloudflare_domain.g.dart | 44 ++ lib/logic/models/config.dart | 36 -- lib/logic/models/dns_records.dart | 25 + lib/logic/models/dns_records.g.dart | 17 + lib/logic/models/server_details.dart | 24 + lib/logic/models/server_details.g.dart | 47 ++ lib/logic/models/user.dart | 14 + lib/logic/models/user.g.dart | 44 ++ lib/main.dart | 19 +- lib/ui/components/brand_card/brand_card.dart | 44 +- .../brand_tab_bar/brand_tab_bar.dart | 21 +- lib/ui/components/brand_text/brand_text.dart | 42 +- .../icon_status_mask/icon_status_mask.dart | 4 +- .../not_ready_card/not_ready_card.dart | 19 + .../components/progress_bar/progress_bar.dart | 105 +-- lib/ui/pages/initializing/initializing.dart | 610 ++++++------------ .../pages/more/app_settings/app_setting.dart | 74 ++- lib/ui/pages/more/more.dart | 7 + lib/ui/pages/onboarding/onboarding.dart | 8 +- lib/ui/pages/providers/providers.dart | 25 +- lib/ui/pages/rootRoute.dart | 25 +- lib/ui/pages/services/services.dart | 10 +- lib/ui/pages/users/empty.dart | 37 ++ lib/ui/pages/users/fab.dart | 34 + lib/ui/pages/users/new_user.dart | 74 +++ lib/ui/pages/users/user.dart | 40 ++ lib/ui/pages/users/user_details.dart | 159 +++++ lib/ui/pages/users/users.dart | 339 ++-------- lib/utils/crypto.dart | 10 + pubspec.lock | 321 ++++++++- pubspec.yaml | 14 +- 80 files changed, 2190 insertions(+), 1022 deletions(-) delete mode 100644 assets/images/icon/logo.png create mode 100644 assets/images/icon/logo_android.png create mode 100644 assets/images/icon/logo_ios.png create mode 100644 lib/config/hive_config.dart create mode 100644 lib/logic/api_maps/api_map.dart create mode 100644 lib/logic/api_maps/cloud_flare.dart create mode 100644 lib/logic/api_maps/hetzner.dart create mode 100644 lib/logic/cubit/app_config/app_config_cubit.dart create mode 100644 lib/logic/cubit/app_config/app_config_state.dart create mode 100644 lib/logic/cubit/forms/user/user.dart create mode 100644 lib/logic/cubit/forms/validations/validations.dart delete mode 100644 lib/logic/cubit/initializing/initializing_cubit.dart delete mode 100644 lib/logic/cubit/initializing/initializing_state.dart create mode 100644 lib/logic/models/cloudflare_domain.dart create mode 100644 lib/logic/models/cloudflare_domain.g.dart delete mode 100644 lib/logic/models/config.dart create mode 100644 lib/logic/models/dns_records.dart create mode 100644 lib/logic/models/dns_records.g.dart create mode 100644 lib/logic/models/server_details.dart create mode 100644 lib/logic/models/server_details.g.dart create mode 100644 lib/logic/models/user.g.dart create mode 100644 lib/ui/components/not_ready_card/not_ready_card.dart create mode 100644 lib/ui/pages/users/empty.dart create mode 100644 lib/ui/pages/users/fab.dart create mode 100644 lib/ui/pages/users/new_user.dart create mode 100644 lib/ui/pages/users/user.dart create mode 100644 lib/ui/pages/users/user_details.dart create mode 100644 lib/utils/crypto.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 4aa064e2e0..5e26575328 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -39,7 +39,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "pro.kherel.selfprivacy" - minSdkVersion 16 + minSdkVersion 18 targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c30b8e1977..b50fa5a171 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -15,11 +15,9 @@ android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" - android:windowSoftInputMode="adjustResize"> - + android:windowSoftInputMode="adjustResize" + android:allowBackup="false" > + tw70U^b8Gi-<0033(vqt~`1d>TaK~#7F?VMk1Q&kwizuVrnYqxb>#F5Cy8B9a~^?xgBb?2nLH(sx0x{nd#4d>q~~`_E80WybC&j18ZSI(+7!! z6{TBWzlLq&w&W-FZ>Ft+!1X~my_6Nkeed3Y}e*aBHMQaqQ21PI&9c8hE#@i~OH9@u3QGRZYN~ zFa83xcYjaH+PAC^z=_Tp`1F_uvZ8#QbMe{|ICR_t+n?#tBt|qr_Tm(LxZ@Hy%TkIy z1GzdjJTd?llK}g^@GAPhIpc!mOJm~G4+RUpN<+;1K+9p=zdRoXZDC zYq=*{Ltrr%wunR%^l)>2btYsvHUQrN-4>r-kR`sd_Y0#1lD45y?RpR98I#6{Yfm zQCgS5OnrmDJrZ4z&wX3bRz?=BQvK5(EJcV&4!)pz#n$A%+udO%NMe;+U69l+-EPGO zRnYQfad6nx7p$x6l|v5$R6)%RV>$as+JA=?m6I?yth{liC8&Z{)=fr39d&@&1_f*_=Z27d=O z*WJ6ai{rRrjG**{>LeYFMtX^)P1QB76Xc^t4|(-T&Mfxl$nZ(4&Gs7kbDxIs=#F{Q z{J_l{A6d+>2c+GvcPOk5qQC@EV1g(xK@^xE3RFR&$N|SK_DVYU<0Yz~Sgbz8ahXN^ z?JwD^nfy)+sr69>J-K!0@dx}i={s9dP&W}2nCVlU6NlA0sDjRQCH^2k@BIHUEezNs gO@RrbzywkF3uPQM@3sFPegFUf07*qoM6N<$g1gU01^@s6 literal 2727 zcmV;Y3Rv}tP))U3HZG3?*E<2niK%Ia?P1Ojsg+S7zQJYGQlpwW9rAAGawi5qT zYLY?|l%qftHJCUM8xs@~d=PvP2YlfpwlS>n?e%T%G5vODJv+ynnK!$3Ncw5zdGp@) zz4!gz``$O-`({l3^Zbh{6{T{L>*6R;oLh#0V%51CD25*?;%axdFkNvtc|&tWm=;cr zn}I*N<4TI5!Xe?<%SXaFl_qkT^myRp0LEQlQKM2iXS`lK=J1Tj<>^?aR}ZF0>5wc_ z_--7;|7tDwkmclL=vv0}3P++aaP?uU66} zON!Zp7%GpPA*M?1$uN&j5A=;ucFGVFY={n)7ZubXOi^N?kaH=qT&T|Z%sk$isrk~k ztD9?k8BG$>q8@*4n?52Cp@z7sEUzfH0vuEbBa{}wTHd*tg%f|eFmivwm>QX}(MXV* zj>dcKjdx%FL+Nk-UL4B8CQBsdzC@zpvv98n4yi!E(e`;sBcLiM&faxkty-;ynoWk3lZ z8v0u5dSTZ^8^cfoA&N4<_?t=;m3z77=PcdL{T(;&4VuQy!_(7~bC!84v}koiP^dqc zQyPEpHs%Y(L zy$|{^7S0qF=B;36@B_?M7n%+o-IbCX&+d6)&H~InejJr(asMD+C|Kq#XvHvrNkbB% z0_wdzSaG_pzju@e29toj^8C$f6|GRNJl|A%`8K-~DA=rE%&LoL>PiIc~^b$!c>QUf`#l=65;q^nc*55gMywYZ|BLQ$&C5%v#4QD#U>`*1?6-BGN zTkfAbQ6+&&8Vp?-VhCW(>C&HH_`oDK9DNxZn)>e>R~MX*CU={{bxT?k6B)0UWkVKF zsv<_j$x^vl>^A$^H!Ei*=aAZnm3cZvCxkuz+;&zB;%fFJy(dl*kq2U!n>F2cyN28x zJhv%CrBh*6@RlhP8qF_W*oo*` zkf2xWTI6&VJ!lFA8?Lm^≻?NFhY~R6Z)CIHo%lBXLvY_GYu$tIL{&!^o@~rRH~r z(lRjE7ug$MBWG(+Xn^c;skoV7i9S_*9fMQmS>#Aaow)1fu4Pra%b5?YgsuDa)lRT> zmbiLR!o{f}G-+$&Ha(glrRXA&7?$YZXsPcN(_7*e&MC5}XpQ$C&foJyp4jMYah&B+ zVIEsR(e}oBJf+#K$TGy>d!E=R-7``U!RbNz4d-|RC&lsMDQ4{8F#n0s8KE{CcBXFI zm&x4v`0ITAbv(`RQ){@1BN38K4LIb-h9=?B%v8Y{v9Yp?_9ZSRr`|eWQXd}3A5+#z z%KANpMo5!PCYYwl@maP8`iP*ypKpkW)0e(o?M!J9c#C*vMg9XeeXI)ORmbSdIhL}S?8x^Gr&NKmP;j{%%ON1 zsunX%j;g%fX=;t?!aLU~C)I!64o7L0Alj*D2z5bmcJ8)SvM&a_i5_{G6EqV+xYI^< zyWMKBl8eFK#+_*zjpmb+H6S}Tvj9JwQ0wf!Dr1wvBVt3u)M94`916H&OI)ZV&ZPJS z`ml$Y7@G-;3}OaZwCOdicmQTA~=RQNbl$4@FmLj8rw^)So{=~37jdpF_cJXYr=Fu(>) z<3snxBjfa3ehU0$)9Ka>Vz&7}+aZtgZfxfYk`|cbY46Ou_i*P?+NzILi zX|vN=QA$-))?EC|7G@&d%BfXhQ9&La*cR&{rg0xtNzJNkmf2$y-nUc~r8fj5u8!_% zaxEGhF}6OIX^6pi*C?{VOx+`Djl-P5F@(niYc#G&8tymW__CAXPhW3jPHT!t1Q=>F z?AV{f0E2U9>B*WWUnvY9uA=K$q`B+(Ijt*?EO=8B>(l_m)aI*^wI|nU`1dpY<_Tz2Yy%Z&TADA zVIpB5%iwbUbL?{O?LnqVt0Q1I4igja<(S3O)@Gz^r@F0v081f9C{B416gKn!3e>~l|kW>;x9~LM;&}&=UcCqnZ6yN z^{`oOAH8|C?d!hcr#Jfr=!7DesF?D~jOd>|zXSh0I+8s3bQVJ1U;gpYldqPWdPbPa zrfc2Z&HY>VW#;cr*ZFFN>ZmdbyAwrBcN>qzo7{JOpn~zq04lvCH5anR*Dx zFP^IV;@meG>x~dzfr^AyBa{{1GUc>&@dsbrrPVFLm&&pSP0=0b(6DXqPXFi8|0&d=CjEPMZYf6pji zV>@LY=D)>7-mX{`QS@X!_)^c*KaY*GL1$e}(mzl8lnDi?-Mb+O4;eMHe zByqk635g~J2Thu!eTY}OEGc1rVY(D7-z{--_lm{8cX$}`;Qz_K^rQu_ zPDjGao_#Q8)dcR%&Z*#9OChw?e+0e8E4mhT1Kbp8zJJ;adsdds`~$OaqSy)zZAakK zx41y;mn{-*wI7E2wS7oIAyI9O-N5;(5nlW%N(BRTXNI7dXT6B}#FV>v^^AsZB zm3c3mJbymE=}zBpEaO;Ek$CG#&;yUVvr%%qi!RQc;d75nX#97cnQ)g1fZc${M@H1Q z77*P{JxHhV5$v==*INon$Gi&jAz~Rx_JOp-1%eeH7_(;|B9CqCxBW&bN=aj2<4Tm5 z6=DWB!D}&P&Pq`xfCL5*yZhSKMKY7;AzJN)Ie(WDdo}C^qSZd8ci7twr5uRljoinQ{QX~@~{!ct&6 zvQov@;0<^^9@}?|1VPV^5nP2B+K=zEfy9K*G8(D~8o>Vr6Awt>1BRf1(J@26)2XdyhuF_9 zVnB%W&)9zttc?j8XlS0k$6fNs5=VIUKq&DCx4ZRs-FjS300000NkvXXu0mjf5cHX+ delta 1694 zcmV;P24VU22BQs-8Gix*007uvZqNV#25Lz}K~#7F#g}VLR7VtmXLm0w;Ib^j@_q=S zywvI{ptV#jLN!evl2(n4@mFoyv|>z}nDm!F`opNP#x&KmwXN1@oBE_xtF2ZkAlOzZ zf*_#CV-Z$mWno#Ch1;{-y_dQ7&fLA?>#(`Z^UODA&di))c7K;{LI|;FOjve2J@%hv z`5LZR)`0)8e0!{~NGIRPpH2onTM=kz!r09h!vM2@p_TGPlawY5yLa$9t0Zo0QeSr(*Kwygm3K(_3c+M|2ROSZ3I0(1mr9FQ6sX*U)* z`-hrqJGslMT!8s7W*1~skbZE(rVy>;-)(^OSz0Q{FUBb~HsAoEw zZE>lQ8V%7D-fd4ZIAI5~HtWMPKU`_KZk2El<$ibHm!FopobC%pu1TOvzrE~uIJk7B zg$zVPk$=$K_`B`+R~18pZaD`5j%Dvz`+x??OvrsZT5N=k;sYY@FH!DVS`e z0f}rRIV)A@t>iu=%{5+aFWpy3q>=Vz*>H0xKf?*e3k;=)uei6zacocd2$7Q#10R6nrp2R8hIixC;+Ds%o7!F`e^H$aFip#aD1&^&!lF@5)9x2 z!hay}3b+g1u3_SOC1*r)$1Hfyl*|~KhKLv={G?U>qCDbB?Jco&J>&@Hzna~)+* z(BK^`P^V0TDDjZDgCQ)4%h>Pra|&P^uh~>^`1A7(|F+{0cw%s1NJ2BFVSuZJn14wD zMF1l6Mns2lBega4@FTD~oo3aB#fNuY;FyS55*nyzYwYG~BV)sq&4Uy!*Tm^j5KOs; zJP=+v9j*|Ao+}53SY5K@`>khh*WXn`1E0F8RxUSvPJ%KGqF=7w6EAf}EQCQLo{_4v zHQ5i2hR_8hw=kXSX-dV@?{&nuhf3kCv;ZY1Hf&xuW!SuJ@TL`PHlEw$5Cd!(@=NBda180+9Ih3s8djJ3c07*qoM6N<$f>|~^Hvj+t diff --git a/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png index 9de8dc003c406636f44780fc4ffc90cbcbce72cd..8e2086be5f694f3861abc9efcda3054e6c85814d 100644 GIT binary patch literal 1579 zcmb7_Sya*q6vqD`7@_2XC@D6WrBvpEP8p8ohD$l(nx>OlL*^bPxQz;Knda7_xmIE( z?uujP!c1yz6V8-cSyqS|W1(TJRlJ<;5%IHCW{P#~mZ~TzqTGNI3WCJ#wkm@j@pIS&2$^bpe4g zz*P#nDny*F3`pg~n>W^zJoC2+60ArRyv&*Fkk&WGqLwt};gNYi0^#jyQBoV<6W^I{}W{TD_bCex zi^!d3StO<(!0-Bkc^nL#=)yWEVz9>f}fI2svDEte`@&tLdxNehH zG47Xk?$EFHxEef5$&!%tXy8yRmDcXz!CC7TtX!bnGm^=bG{c1Y9Nu51E6dhJw*)D) zv(j|4#xpF%e0+?`syHmA-h`(%>5!aA_Efm8ug>raEhPO^xClMj-X^||;yP9a47X$$ zv$q-+1%;QB%%l2S2rCd*e#kn5~FxG;$!ZIkM&6m*q;*(+S7MWXS;A1h|m=2z0kxsg#?|asgdmi z=QXR8uz4Yxdyqm0r=>=JQ`_%GwWe1Q>!}lkun;b zCd1KRe*|k(@)W<+^eA_O?2w2Y6z}ZD2!n`Nu}p#ZJF6AYg2q^?I#fyB_u63ij=nNO zB79%1+T!uPA0#cb^8E4&p{ySMfQ8?UrZ1Z%wkuYzckNom_!5%H&*S{|53%E*^LL_} zpG|kaM6OxhSsGD!Du<=6^}lQPYDzKp^|g~@i|qWv!<=7FBpX~_KkCaJr&=V#L20F% zI;?uXstt<$wQ4S&LW*coORMJj)zNa^vtHbCWWnqC&~U%P8Hq@JD#}f2-a3ZZ2 zYJ>DAjY7T$v&T*;s%g{dd9;e0?J%_qb5h5kdYN$;Zdk4xeAj^h9_ln=2c@dA6tOwd z)AQ5G43Pj0!4zpKR zU2mkCUMe=}jG&9#E&pYp8ps2Mt0rrTbCddYVwAl&%;IGd+V5ru5nt5!xfJW**q zay2JP}lBvI8oxWata&h|4^oLtd0B|Ha+csJU Gr2Gx@T+_t> literal 3706 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 Y0n49SU`CNs{Qv*}07*qoM6N<$f&_LQ`~Uy| diff --git a/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png index 01b3e8918b497e1ddfa10cb4d1da664e1e54b43b..898cb8046d2ade0c3ba0b668009a22de7803526e 100644 GIT binary patch literal 2212 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 ICTA1=0UQqMTL1t6 literal 7819 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 DF_7IW literal 0 HcmV?d00001 diff --git a/assets/images/icon/logo_ios.png b/assets/images/icon/logo_ios.png new file mode 100644 index 0000000000000000000000000000000000000000..be4800ed6f83fb4f66ba481106a671a4d7332eec GIT binary patch literal 2988 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 z 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 delta 657 zcmV;C0&e}{0-gns8Gix*0008(idp~w0%b`=K~#7FW0|zMh~fYL{|rFz9|RcwL%9$( zR1nIAGNFwBEJ!*TkN^q?9l#`6{v&u$CbB-biC7I|f!X;VrV(z$e}tC*|6e_Mf9t{% zEmJuGF&?-$3*5N~-!lCF^XKpL2XDWB{mCQ1DJCPpz{qg%=zm?uAcOtuE;xr7B5eN8 z0CzY@=dYiC4sE=6dhbo3PHfTa@#Yj15Jf~O6XsDgymmrvg%H;V3PSSgVp|rTh%9uJQ59ukX8iLT7(oAL)NBSi=lho*CQfQxJnU#T!|Y~c z2+FXTS%14_S>HbY6syz*?`c&VA(r2{^i)D#&@;x20Tm$p3t-J5%3cYK zUU8got!1 rtt<>gST*2uHrxmz0Sig0(EtEKhj@QLObV6&015yANkvXXu0mjfZzMkq diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png index 8f1ccf475b24339224f2e6bc1ffb6ab3d8e8ffc2..af5f0604e01f00e18deaa2c55263dff7fbf5dd8a 100644 GIT binary patch delta 594 zcmV-Y0!%h9CRs=oAKqZ$FJ0xHQk8h~akN|6jCr52lrWUSfz1;V2#?VAO$>f}!WYzkmNi z82>;VMv@I=Wc<&-#6+pH5CFr0E}lM67B3LHlWd@>>_>*lrGFiXeDFzv_uMF`%cPTcDW|?Hc78M2=@vjWdrY|TmhlaVB zk)eB$E`z+pR|XZ?&t#iIH3wSgzGCpQdcwfQ`VSn%ApG+;GegA`V}_|^Cm6(qe+--h zb(G&Tv}K)xXMYNFoi_}icKY7aQVefDaxgT`(q))dd3xX+Xlw8iBggvMJ_b7w1nxcM zB-?DNIPlkR%#s-tz0?3yap3mjG7P?Uj~V!ReuMcS2QS;HObw%{02mHrW@ct+Yi(ipd2b7lHwYaF z0z!hoT1!Ae0$8CwqPKf6z|hMigAL$x;LpE041d2prl(sN{xQm6h~ab~yWCuwI)+#< gbfb8%fI;s-0Q#eh7Na!_ssI2007*qoM6N<$g80)BZ2$lO delta 1427 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 Uc!82InE(I)07*qoM6N<$f|d)jbpQYW delta 2149 zcmV-r2%7hb2j>uw8Gix*006a~P9*>U2rfxPK~#7F&6){J6jvC4XP1G6l|ya>ltVxe z5f4--6sh2aSJl{>TEy0xn%E<4t+q*%rmcxR(l)k9lcv>J&o(u&l_-cu>roED69p9H z5RtpfvD~{m{dWguXWqPdGmD`8gS&6u^?&cp|Ni&Cx6rV|70j6hs(l3L1GmXhWraJ<(y( zJiUmGa@nH^G%9`36l(j*`d2iP(ICVrq6HN&O>9w&tBdadm#bVCej!Rt66&E8)ENt* z3AmC&SFm1{IDe!O507siBtLJ}A+cV^bbgV(F`El^f~98#w})A~BI(vO>#NHe`nm^P z+_mAc0U9TJIdu#NErToQLg_RUZNt(@!RfM`BSi*-(P^ARPglRIhxWy{QYJ+;P*>|^Lym)n*19;ld5)VH?j086@2GX)`hn7_(uM_VXRySqc=)=4S=W>{ilN10 z$3sg^Fn>ba-l_-FEXk|x?&@RBj59Vak)KmKBWd#Ltw~(V9(})IzyK9G+PZm47>%Pn zjCru%Kx^y}y@+y}mnU}Fk~=&o&O3DnfQ$wc9}yu&7YxIc7T5mv-3610Ienx!=Wr3f z8vD6>>(Q6Dr-npN5Gl0^E$Pef6Kw9fB){s^fqyG~Jp(d`xaNhY%Z&yjc7&`zw?*gg zanM*1nFnT15j@?vRC!`=KEdbU#$er*OmZVM*D;#Jy$YcT>O~nP1=U&m3i$e@rdf9S z(XK^?M5rva5HT4QH|ziWDG$~@feec{-pknvAu%@mBLSKmII~}Ejh)ATylfb>nj?Xj zpMLf&%xH)1G zrO_D-DIc0JATGP;+}+BON3z5qanD68%bZ6EM?Bn(BBN&*c^e^KAy`TV2MibfxP|Rq zoRHq>g`PxQ!ImQuZXpVr-!81_?(D-(Fn@(X7rt2$ig{7WS%`5VwBFl2fK2wn^|N7a*fa$4enB1tVhU%wN)F2?w10Gw zxw)>Ti+f(aDgNG#hc_!7XJmtxpeUnti(hk-0U6$dlu`M0 z^b(*UO19Tn_FbG)V-K@XWHd4+BY&f&RYR@ipiz;&?SKMC<3wldOgr|&CGaYcdHCyd z2oT~@04wu@MPNl}Zx%A6(K;!VqFJ^;lbt$D64xoWje`eR|8`3Dp(};C1}UaNz%otkHPurAXx=630NV5>(cWv;0#r4XRAM@*35C_jb7 zD707)m_b;K|IL4@D2w~6Eq`we;q`8YP*E#4Cjhj3a3boytk@bLgiZIi0b2HzM9m4} zHk5P6u5bQm39`&B0W^si-VcO|&!Mf8=x_H!Z#Z=dtyMS zXMI&0q-)9=;g}ec5F&)OqwVeBP$PwY^YVT8Q>kHDYZI1EO-hf3vVW7m6vANGn#n6; zRBFWzk9@FY1?FbOs|i1Ul5L(Xih?~XFwEQC+nEQgj+{NQB)=L<%%x2RroB}UCm@yO zQmW!sJzEN)%dC`e<-`#WJxkydrP zAwRdQtf-bi3~3l1mzlJD+LW1rHW5>@E{_w~vDUqjyl+RY+?x566bbCEH>D*mB8X~0>iz*RLZZ_ z<(;}yb*F)U)rk;mT{W@KgeI?={`k18*aj{3kC8J2;ZN71hly`%>gxQryRT;e&LFVk zK%@ol#BY*&aHKDLco{9R<%c4)%vuEA1O9|nZMHh)!e0G0u1p6$;FQZ4ZBe!(N-WkV zkIRbu&lhO9P1$23@=+cq{|8)F$UlCLv~Y|?{^TN*r^(8Rto!_5P$KfU|C#Wq$Y^d< bPfY#;qbq@~k(%7200000NkvXXu0mjfgYg;j diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png index a59a8c070234c3bf93b503a35205f69504fa4f1d..856c5156eba2f7d8451f47030371b13f6f9dd0ee 100644 GIT binary patch delta 510 zcmV6&-{Q4uXsLSY5?Y6hRQBn-;~Xi%^jEPf)?d#X&^tU>}O0pg1}BD%w^N(GO(c_;nsL89wdd4% zWbgz-J?HtO`DA&u0X3Bma5=BkLj{4ttlt6e#2##xxU#6VI*!ifYaE=KaClk{x33kx z>0Ou%&&r@x=6^>lO$DLT^597wne?_JbX));8rU}1D0f%SSEos}t%im9zmytTQn*n&|f zsYGHN4PqtU>$0O1P2NgxlNJ4(Upbh)05-mVEuE1^n*aa+07*qoM6N<$f{GjE~@jL~mGMXkx&Cly`gpg^B^?p=gDu z5Rqr;uHRC+ot^HN&`R4z9-zYB1u zpa1ryr%4$`B!3g_N|UDzg^`<{ob7l#_~zAz#rfsH8RWF=_=Sp1=2$Qy3b{K*VI^!l zF+63-*d*dg5qZS3dwp#UgZ@>2aFTD}oo~gzw6JpjW(Ui%;Bvq|H92$c#u1?ckdSA% zTMlaUh)xKnVeGV7$E>E zwbGt%nf>}BumU<$a(uWBBJgnkBm|m5h-G=Z&5;nLQKe=l2BCZ}m&=ZxE)`z!I}6uA zWcoHWw|~K?-?=YyE#h2hWsWJufJ1T7-wk{kfAcwiPr5EvEv>JhyU(|()-yT9HW=Tl zZEtq=s|zE_CYXpu~A_<;N=F|F^c)`i!jPAwo!7*dCdiB zk87Pw>z!u$TmqRBJN+IW$#GVMl+DYtqwg?f;h=p38yX}ba#z;y2rflXQH$!T23L0-Ka~?HG!wvXfk1?xe|Y|wOc&5*cPaf zzxv6e@OvF|S!(#_TtpPyzu`jM@bmu*F2wy`Afo*QJ`h^uK6vDN00000NkvXXu0mjf DN&)5h diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png index 9e63b9a8f4cc078960f138b0b9caf4fdc4108d3a..ce53aa9f67480438a94fb7a9fc1a5107595763b7 100644 GIT binary patch delta 895 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 b=Ujre=Q{=^)V(rY??#Zv5id9ub~^PdktwpF literal 3271 zcmV;&3^?2Qyy}3&AcH#4}ODfIU9sd&i-P+#$9cyZqe4eJ0(6+fT;gCOklkLvD&mCW75a zv2B$)@$i7}0e=V!SRW+={c?DK?!FpK*jpznQW+7$DkTbfd@ZUOHd-rN5kv~qCjwr8 z7|hUPOg1b#RO1Epj$)|iCF8XP_|BKBCt$++UYZ!1K$&W*fPFrMjZH zzP-6yuh)l-51h3yF*Y%ry(3pGeqT^s0?Z@PQBwc>=A|Z+5vNkc5)4*|-p;0FaOpz4*!5Uwn4$Voq7= zW0U!H!4%6eut1=I)E&pmay^}WcN@F9JFM28fxeyr+wce|Gs^2Z#FykF)st zn=wn<(b4U)#t|DA8fBT393k&7edV+Z$4eV)+6MZDBplH=7b+Goypj@7QQpyVr?a%6 z>SkeGU1cj;j{OdIb?%ZWDf8pxhIhAF;WH*a47&w-`hU zzJP)PZiK76-jH{o@J>Yw<<0|izzWwJbijhVc4TA(1PES04=q8=Hlk>@G89>$8NUv< z(!kpCYqe(%7d2G3A?@%tpC(Cds%`)LHbkGb{ks3s%&pPF($& zyDUjJlvfgMi%w3YKWQ!*z z0$xDn2^~R8drJ=lMe>g6Cxu)rW7YJC*kGpHNO1_D4)W=%qAHth>1Yrqf;aaQ)JfS=FoS3ZkduD^y@;ZSYb$JZ*>dh)cE+DWrmZW+=qgW z#+vpnaXy2!M*UJ;C$4f`hDKUuE=(voU#Vl62&s=vmY7Bm);VHFvVcSxS90mL>J*Td zpqEB3BP9hodnl=Y>Q|4>T9^QNs%_YYh+&o653gbp!sDh!GOZT2vnB`@3(r@Gs@NHc zoEW0o5ekFRkeoUpX?Co76Cul%h^T?Yg4`zi!C`x!vq$wsAun0@cnazuD6<$ho|005 z?tHY6Ua0fcKrmleIx{jt==eZ`Q3yBPfi4T|cMca{t1(jyPJ?F>iXYqzl$bVk={fdwN zbgH+rAG0q=uSp(3Cabs>DoX2*?zt$)On)TqxmTBHqd>>{9<=>Y3St?!CH_m)#LyRC zTe){vZg;ztWQd0-fKP89FSJmIWwn8JU*Jtru*_aKZhX*&?LXSR{W!lgK(eO1`MuYU zpeiJdMFsF(uY;U&-qNXhy_Rz-%@aXKdLDt(1Fjpr9JYrsF1e6#mi1ef?|bWXcZYpO zK;GS0E%GUda(qm6^zZpblQC_PB=SQfo!t%eiB7tWCWAb_dt0P??OBf?`;}H&frh%E7-6- zOL)J6@+D<$6aX&e-jE2#O^c$p9}5;w>FC>RHqLk??rPpmp&0HA+-kxNkvw`NGt%17 zmHX)xU;$_a{|6%+kL-M1?N(TWXv3t`*vQymhEd?4<;nemz?7qV^IzWegpgK9 z5E^OG6}yCGornX0rmnn0g~BC7tLa(OR<4_CG#YHfwol$Z&A+oEG+goQ97#m00SwQq z1w>5>jhh;IyR1%=K3?}=PK;tPflO-_J@A35u{`Kw|!6vwAIr|EH{LFKO@WELHyuiGLDV=w) zP)8RpNJ>U*BYa!5He>Y+X~3oxl3xrltd8mF@kJLaZ(OZK3r~D}nSTH$83qus^yyS6 zzg1iZO`4qXuZ|+Kko3!!jE@gXUpbB5S~A#9Ur`tg`s|-AfGr(11)&fU-o3j{X0Dl) zp7jIC+m}EDu)rTc^DJn7v;`Ebdv&o{e9+0WT9g>=ayYO zdEMK`D<&}nHiI{em*3o zntu~T19x{v3BcCa#Bgw9b(O8B_FuhOScld!J>Z=-cjBW@%z#jROvlf|lPsXy9)$NV zY+Z5ZR?D@oZDp=?Res1Jv)b&?CIXv44~YN(002ovPDHLk FV1g^uN&o-= diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png index 8f1ccf475b24339224f2e6bc1ffb6ab3d8e8ffc2..af5f0604e01f00e18deaa2c55263dff7fbf5dd8a 100644 GIT binary patch delta 594 zcmV-Y0!%h9CRs=oAKqZ$FJ0xHQk8h~akN|6jCr52lrWUSfz1;V2#?VAO$>f}!WYzkmNi z82>;VMv@I=Wc<&-#6+pH5CFr0E}lM67B3LHlWd@>>_>*lrGFiXeDFzv_uMF`%cPTcDW|?Hc78M2=@vjWdrY|TmhlaVB zk)eB$E`z+pR|XZ?&t#iIH3wSgzGCpQdcwfQ`VSn%ApG+;GegA`V}_|^Cm6(qe+--h zb(G&Tv}K)xXMYNFoi_}icKY7aQVefDaxgT`(q))dd3xX+Xlw8iBggvMJ_b7w1nxcM zB-?DNIPlkR%#s-tz0?3yap3mjG7P?Uj~V!ReuMcS2QS;HObw%{02mHrW@ct+Yi(ipd2b7lHwYaF z0z!hoT1!Ae0$8CwqPKf6z|hMigAL$x;LpE041d2prl(sN{xQm6h~ab~yWCuwI)+#< gbfb8%fI;s-0Q#eh7Na!_ssI2007*qoM6N<$g80)BZ2$lO delta 1427 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 literal 3053 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 HCzSpb`t0L`4191E_sQK z^X$Y0W5*8I1`HTu43a=Jfj|vVK@#e{OQ$ROPJ4IS+nwE=*_}I%px?VE-OYUS&9}du z{pOppyZXQFex7l_&T!!QLp;kf!EP61ddP8drF4q^vhyp)HIr`^M^vDbCn%ardN_KC zYKA}&dc^tmLN(G2=SG0a7EOUZzdZxeo{$uLq9xoJB6kSb@F3dnc=S7ioKWBi^{$dg zeYo)kLv*20y(F&}=*8m~YIKmCfA60IFP~;H?INAw_15V8-(D2aD66UY4WGkLEb}B< zgfH*eszNiB$kKObK`(pNp|VvpXQgf5zZ|_sZCKUG3|M4YmN!E&LEeaButljmLn)$h zs`6*=>{mb#EzTSEr-7=LGzNn-Z1rYSrxVq9!!aV3veeYAsPz#wXNd(_0`!|LMQ1B3F4niycbNMu zjD{H&W{gdY7@IO;|}rHblR|}5OZ&TXIl@eFmq4d z)slt{zgQR%GYm%|X7#9%p`s>?!}2u`MCz+rKY#nM)oO$9G4bI`H_n_qJ3$|ygP#pm zty$mY=Nu`vTC8OSwFm!`bJx?0dCgk3lb3*=QvZe%ipZtWI}c)hBl|$1&F1(XHaz6f zmsW;`1-V6{M}@E3oSrgo^!7InS^BMc*=0*N%!nQtPRk^<8)(oJW1T!1mZ|%VmWIy! zljZOwHX-7{7jEXV>_*az_}e!v*tIRoX0^lLM_ybJXrQyl$VWSsh-Xo};AVc>mD}CX z3tv)KCWl9diq$-OankX91+^6|6_@I(N*W;!QB)h>e&s~tw`F{%0oQeJx4EsUv$?*b zy`{UWy|<^cudk;cqA_rB5DDn?+Tc(_P)K0#u%NKWVBl+btSP{t=Q>lQ-vG_!m+IgP zNG48-l{hY_C2jSTo$qDB_lD|LQKAW>DTPGiw>ZqDgTCJWk_*-6kChhXR0_KdUJCao zT-q}ijUP89Zv51^z@PvzGaPY6OAma3vl1C2)|{P~o;GgRwoIs`v$aQB5+B4wi&Ctp zEdyn6k)A$u5rz+4ZM`CjMOkJB&d`a2Metd-ISsCQF{^A=o5f;f%ZkOwgPJvrR;vYh zi^ayVTj5ZJ1p(1gHIcL2)71xEQ)ymJQBDQ)JRD6@v|<>E05s?N>NZxB-R3y8=&_%x zGKl}!gY9bXfruMI6#ls(ABABNEpsw)S$2!t3r|(-`}AaITQ4cC3WCw*x{mk%wAX#P zz<~SRmv#%aAuT!m<0becO&@jNbISsQR0R&`!dRDy)Fy3_0(Lue<#3q;(Xx(Mm?AGA z$gV1F{Nyh`K&OhMO$?XMSM7W+hMHo!w zWnW=gR*C!*S0Mg@P)D%_Ju$_^4cWoSmBQLXU!8@p)SV)fkxs!_IYZd#n3==SCUaAW z158h+*-5mbu{4R_k-0@hG`YN}_T#MwIckVmM%jXS$tnS|c9nA#7(^@C$~2f$UDmYg z{Va|$MKe~UypyzFH4NgPZQM{P_ob&CbH)KEw?eO^ilQ75Pi+RC-g=&~%K=cYTRFS~Q5W7NjKw8@Ah3$A4oJb}6Q4zDhTDaorj zbNDho#bSxLVj5=Y`k6~M%y0~j)x|0pEPFeS#;(t1v!D3BNIlEkL}O?mgNh^cdTo4C z^o;azljkIgOhM4}5;Bu280P?!Xe=wU_U2#Cy^1KT)Q9K;biaM~KE&u6rOQ*`T1MhX zh!IU#v7KqI@5tDF0gf zyHm+#wH4)5q6JjDk%-t~Dp|%cMy!CW1d%>6qJ@Xl*4$lH(!dv^;YNaj1L1-d%E_99 zUnxG+cxM(EJN_k=HrKUtkAjq9Q)F;dT$nH`c$i_y`WexqJa^4{ZT#kgd&tOF!9CGZ z-@yn-9N5~!v^I9JKPA|oJUijGhvy5^F(WxD&6(UgD`8CSwq0OTcqC&}Myz^p-e-UP zvHW7aw6756iAf{UyyP^f_JM9FBYLp*p3XjDHneE)u=hT@bmz9rOXo>8`+wZS-fJe+RiaZBvWx@J6KpaFd-C3Hvo|_j zwX=8Zj$7e8virMMtGWA`#h<=@sIjIEsX-!4K?!47i|Lx(4T4w1YO(2bTDokj?F?-; zoA9W3OCFK2!#4eX<;PnO)|NN(Bs*KXD~tJIxC7Xu^Pu1WUKEJ$nss`le{k%frs$nn zkniijsLpk$gQB6PpnIQPvie z3+R)tmNceBCSn=w0x~uY2-FEydnveUy~-ZewMy-w1-bW|l?Vz6y#M)|cfOZVR!}>b zrG6gOZtv-m-*C?BOFLS7gcGM=p{MJh(&EJRsoD+MCZO8pR6)E$cU@+pYGq8O2EbY8o;l zIR$$0>{X;Tk?p@~p^9j`b7OK0Z_vRwZmOs=_gS3JV36iT!>oNgwXwDh!ePFCB9?`e zN=`J_RUmr8;7~(sd^q*y%uv{fuF=e2o}3S35YO!Hj=r3qE-hG|EUD002IA{GpIY?h zmYsuH6c)~<$m;Djm*iIq%TAh;5NMR&XRQEgpSBA~oD>5M0hk>uIAHzp{RMNEPUKE7 zc`El%9~5HX6-N|N$udXsTt*2PEG#=cbsX)dRym<&f3y=?t#-n+k>`(<@$7D{>p1yC zQQE30+(c#XrXr(WZfUBiw*A14)55Ybqr%5ei<2-<4QM=p#%@oV5uck?D$L0_Qk=Rn zg^mA7x6+cP_x1L7cl5HgXmwf$X~Z5E0j7fM5T>WEnId-msfU_Pj)TWJZNZp>Uz}-c z>f(viRkmErsRYL-s|-j1c5GG~FCCx#eV?4%zx@=O4t#}2g(M`!+ywzPw`Oz#OIo3`RW+$y!{2EkoYG z9S>P^t@c`>?oR&6L;sK88LG3*( zvu>Jj_Gs~yqB_Qt3%E$X-*JZBlqCUh^ivm%$@unytA08YAgzs^`#wDtV9>Mi54f_t z>?=ZH@G;=xq%Bkl<#*2Vp<(WLJnh5R_VZ?x0HyggN4`0qzFNiu&cAhX!Krdyb8|xt z^-%kySqWWjJ%@MY3dO){-TCw)oVjc@p!wXp;c+Ht*GIlS&zG^;fA}KD6dpWl@dOD~ z;5t@4I1hOzsLBT3*4TC6vr|Pmm3=+@dlHy|1sX7$`ol!j(Ua*kd;ceJGLY72S|fn;bd zOy{QDeAg_f5#z|zLhar=Ax4dh`q{0MGIr-7^6bpMPfvm;S-57Z#KaKv{&SX0gipWO z`pQEe@pX`ND$>G}X2mbtILimkneoyiGt+OI+E~+Gc)CKEE=5)68q^?RaMUeGB zbk}0WPmSC7gY56KWbD3h;dt5RS61UMXV6`C zF@^-*`|G97Cr|hU-g*eER;yY2SSkz?&ir%5Z~a(whJT+6S1kKL;kk?wi2SCfkBuK6Ej zGfPh%DyqNQDzdys%r7@<_z2VNB}o%!jv6&K${$!}eD*R0E+CvRh8h;EOomT+Q7!b7 zwVo^gYFG{p3z~P!q+9NuqrIk%LI~dxjSSaDPag5i)^%ltwGdF}ow&ljRYFvQILlg{ zW=wM2jP!BSQpa*{nD8HXooLxfD-G+rQ%0<~e{T83y2|2)wx+I@x{lVSE{ORYx9&J@ z-WXH@p1@!X2rvYgB7$KAA2rehBR%+lyYLe)frJ-{#+?^*k!TDFoIE=LKCWatM0@>a ztHo^X@3+`2HaI0Zy$%MP0fBl5&j+FiUw1HyL5*mN5Bzq*@zxa`d>F(WpPlpf`ha&{ z;UrT=zKEp6^~A3ml$Ww3ORD4-Bj1m~Cz|qt3&H+cb@_e|`b$|35Un;*5%GJ_i#iBL zm^TQ&ZqV6#M^K2O)O7_4Z>^A5;3e7X3iP&wp)f?T8(tY1k`7(GVS~Sc(o&Ys3SGBQ z{Dw}&xUu+kL+mwsba8`{%LRp-g~Tz$?;yO<84mG_fO?{bXvG4}*Mkf}0;*r8Fa$hY igH`Yw6GKG%2>%270$3kWP>`hn0000@WiAIGhkiBQPML?Vt*R!sBbrcG#;<(936?Pa0M&paZ_b({P?b(Hy)&Ci_t z+^&^Fnxw@N=KLJCTaUwqM&0NzkLP(_&;9e<{qg;NU$4*W^ZI=Ldw;Y1v1hb24rr*T zsA&0kqt5T#q<@dP+Rk>NI*C+N)S`V*$gh$BOVcTldLTo=N{GZsEwV;DuST1#F=j-b zHdoh8btor$dYc2k*Qx zhvpelZq@H3qc?{W`z|?o!Z_-CC+&NK)BiU2Z|eS(so?AF(`6pgD4=V4>|B<{y&-Vw zA*artJg-Z?7=8#&`p0?0D%8OJ6-Z0#dgf#(3XN&1d_K*lW3Fn3xu369Snq?}ql1tc zxgo!XlD98lpizOe2btNueCLJ@Dx5of=@`7bZpWoJOfPNj3GFHk#SxXT{Qh8`AS<&- z`)FJnhOj~b%vigrR^`nw6W)NCPCH| z9>bZnHC~N}8p33zJC;4*&a`t=DK_?RGDwL!)g(EEE!|SjKAP0`}Em@l<*3~ z>v;U=E%qvs)v8%@vKlBbLdeHc=j7|aaD>}v$Aq~;pM}E;+wvAjgMOZ z!)shP${HXtZGOLmj)q+woT=!(lR^ZrFQuF^5<2NqE-!qLNgnSjrb=CgvBGZ(?MiT| zlbTuZxTX;P+}8QBY`+kybYfwy+vxb$uR%{NZXB!dSK<$d>Rwn`v3pi?(bMj08z~0b z4a_TRWjdcbmV>%WUN%OuTiZtGu`yP!LH67r?Hd!-?oln55wQ*S@~*K{LdHw7NCrei1hT zvLVZc$#Hg#hal^6&Npykj90J%KOt1g#pUXlYWr(+%hIQF6#N2`DEwJGEdSi}N!_pd zU_SkpTRsC{kd~y(s+zwyIJ5NeE{j86_+wwS;#Q2A5n**&35baJEhq5TgL`7f7{MgF zIr7qIMJ$aM_r9J)1)f#Hi!*EcmIY5nJSr2dAcHB-oQ-3m`U5H4`9mgze9E)YDa^qP`UbeR21w<4sFP|bs{y_$Yxw_TA5Bae>`S$nDTrSrU zr&!g!Z)ck^P@C&uk%gv2p*>u0=-Qtoy=eb{w?3&8Kp1cL`7tMl64UYy({BKJMez-w zdaU=LHCL2k(e%xez8%nj@6G9cNAy^>#o%#|0NHF2Lm!cUdGNQjC0#*=&0hnSKxPl9 zmX&8<1>wy5N4CW2z8pSdMnixvH7uHOAYLdnBYF7#04uueP(M}Cr)n%~jF(>7Bs}m& z6h4kf@6<`wvMzX5RLSnzU7WLZi!jh-O#FY0|H;)Ix^M3~mtEkJR%br8^MF)*&{$NH HCzSpb`t0L`4191E_sQK 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 VOS!Ah_MamjOLH5u3X@y-e*ve_f^Pr- literal 7277 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 Hu0mjfobC@H diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png index 43a509f5d011408c25c1f78dd40d87cd3ddf3d7b..8b55ab5bf15c95454c240a78d9afcd6975c020d0 100644 GIT binary patch delta 1179 zcmV;M1Z4Z97NiM~8Gi-<0076AQ7Zrd1Zzn|K~#7F?VMX^990;{|FgTZmuxQUZf#?8 zYnv@?nvD$v8y|`YNq(~q1L8PG# z#-wSqbfaj}*pzIW#NF6rFXK$4X_K8y<}=L9xAgpAUgmso{(t4L>q(9Zi^$S!68UNRoowrWw3)&bGPCVkoTVd@o+y**fR!CJW=t zX2;e(JpSOHw#{b-*0c38$mXz*<-~=R(_ujX2hNMis~7EiY?f8p#P6 zyN@>EXln;bgK4MZ@E4{rcr}Q&4;s<_d?!3^XTNMH2!CN3T^A!bbfOL~Z|ie3N5Kfw z_~wUd)Rd>N`Jq1?%TQ3lG~WB-zs}hl8*ya*f)kcgB<%laJ&wH6ffe_pY@eT=8g)rHZ#oI5O!Nb5 znSUiq<4QtiBTIvouzOcu&pX!;%|GWPyoBksMd1H;e&ngz2qcH(66NHvI}H zopIZkNFO%B#!|)jwxf35@o-rN!wDg5hJTZ%E1ZsC3O2$D1tE-x5JtpMSXEUe0zNMi z2|jIoE{bCBM|Xz8BH=LF54?fxEiIUwoWiomBu>29V^=oQ_}~%d>dr z;32pqpd^^JBNtmttzlcYY(ZDo&-k_XwAFdoV@jAyeP-FeZy)yV(Y`nBvN#fNOn-Mt zzu$+py?cO>&#cVD9@4g=D3JeQ$eo7RhY=CNhzMasgfJo`VcHL1l0`u{p#7c9LePXs zA*7PpOTMZ9n~5!o;!+P8lIJeNI+8G#Cj{ThPmxV_E-D;XyzWwXBbyCt$ZMEf(mZ|K tsfb0Nh!93Z2qPkd5fQ?O2w_D21r%Az6Mn*DA=dx^002ovPDHLkV1mSSH2VMm literal 2852 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 U=CyD0AOCIu+!kR&vqB~P3r!WU#Q*>R literal 6036 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 literal 6717 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 AppSettingsCubit(isDarkModeOn: isDark)), - BlocProvider(create: (_) => InitializingCubit()), + BlocProvider( + create: (_) => AppSettingsCubit( + isDarkModeOn: isDark, + isOnbordingShowing: true, + )..load(), + ), + BlocProvider( + create: (_) => AppConfigCubit()..load(), + ), BlocProvider(create: (_) => ServicesCubit()), BlocProvider(create: (_) => ProvidersCubit()), BlocProvider(create: (_) => UsersCubit()), diff --git a/lib/config/brand_colors.dart b/lib/config/brand_colors.dart index 0bd0c44cd7..c68d6dd88d 100644 --- a/lib/config/brand_colors.dart +++ b/lib/config/brand_colors.dart @@ -1,33 +1,23 @@ import 'package:flutter/material.dart'; class BrandColors { - /// ![](https://www.colorhexa.com/093CEF.png) static const Color blue = Color(0xFF093CEF); static const Color white = Colors.white; static const Color black = Colors.black; - /// ![](https://www.colorhexa.com/555555.png) static const Color gray1 = Color(0xFF555555); - - /// ![](https://www.colorhexa.com/7C7C7C.png) static const Color gray2 = Color(0xFF7C7C7C); - - /// ![](https://www.colorhexa.com/fafafa.png) static const Color gray3 = Color(0xFFFAFAFA); - - /// ![](https://www.colorhexa.com/DDDDDD.png) static const Color gray4 = Color(0xFFDDDDDD); - - /// ![](https://www.colorhexa.com/EDEEF1.png) static const Color gray5 = Color(0xFFEDEEF1); + static Color gray6 = Color(0xFF181818).withOpacity(0.7); + static const Color grey7 = Color(0xFFABABAB); - /// ![](https://www.colorhexa.com/FA0E0E.png) - static const Color red = Color(0xFFFA0E0E); + static const Color red1 = Color(0xFFFA0E0E); + static const Color red2 = Color(0xFFE65527); - /// ![](https://www.colorhexa.com/00AF54.png) static const Color green1 = Color(0xFF00AF54); - /// ![](https://www.colorhexa.com/0F8849.png) static const Color green2 = Color(0xFF0F8849); static get navBackgroundLight => white.withOpacity(0.8); @@ -60,5 +50,5 @@ class BrandColors { static const textColor1 = black; static const textColor2 = gray1; static const dividerColor = gray5; - static const warning = red; + static const warning = red1; } diff --git a/lib/config/brand_theme.dart b/lib/config/brand_theme.dart index 477b89802a..0505e471e0 100644 --- a/lib/config/brand_theme.dart +++ b/lib/config/brand_theme.dart @@ -23,20 +23,20 @@ final ligtTheme = ThemeData( borderRadius: BorderRadius.all(Radius.circular(4)), borderSide: BorderSide( width: 1, - color: BrandColors.red, + color: BrandColors.red1, ), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(4)), borderSide: BorderSide( width: 1, - color: BrandColors.red, + color: BrandColors.red1, ), ), errorStyle: GoogleFonts.inter( textStyle: TextStyle( fontSize: 12, - color: BrandColors.red, + color: BrandColors.red1, ), ), ), diff --git a/lib/config/hive_config.dart b/lib/config/hive_config.dart new file mode 100644 index 0000000000..b0ca400984 --- /dev/null +++ b/lib/config/hive_config.dart @@ -0,0 +1,53 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:hive/hive.dart'; +import 'package:hive_flutter/hive_flutter.dart'; +import 'package:selfprivacy/logic/models/cloudflare_domain.dart'; +import 'package:selfprivacy/logic/models/server_details.dart'; +import 'package:selfprivacy/logic/models/user.dart'; + +class HiveConfig { + static Future init() async { + await Hive.initFlutter(); + Hive.registerAdapter(UserAdapter()); + Hive.registerAdapter(HetznerServerDetailsAdapter()); + Hive.registerAdapter(CloudFlareDomainAdapter()); + + await Hive.openBox(BNames.appSettings); + var cipher = HiveAesCipher(await getEncriptedKey()); + + await Hive.openBox(BNames.appConfig, encryptionCipher: cipher); + } + + static Future getEncriptedKey() async { + final FlutterSecureStorage secureStorage = FlutterSecureStorage(); + var containsEncryptionKey = + await secureStorage.containsKey(key: BNames.key); + if (!containsEncryptionKey) { + var key = Hive.generateSecureKey(); + await secureStorage.write(key: BNames.key, value: base64UrlEncode(key)); + } + + return base64Url.decode(await secureStorage.read(key: BNames.key)); + } +} + +class BNames { + static String appConfig = 'appConfig'; + static String isDarkModeOn = 'isDarkModeOn'; + static String isOnbordingShowing = 'isOnbordingShowing'; + + static String appSettings = 'appSettings'; + + static String key = 'key'; + + static String domain = 'domain'; + static String hetznerKey = 'hetznerKey'; + static String cloudFlareKey = 'cloudFlareKey'; + static String rootUser = 'rootUser'; + static String server = 'server'; + static String isDnsCheckedAndDkimSet = 'isDnsCheckedAndDkimSet'; + static String serverInitStart = 'serverInitStart'; +} diff --git a/lib/config/text_themes.dart b/lib/config/text_themes.dart index acc9425fcb..54d53ee48e 100644 --- a/lib/config/text_themes.dart +++ b/lib/config/text_themes.dart @@ -18,6 +18,12 @@ final headline1Style = GoogleFonts.inter( ); final headline2Style = GoogleFonts.inter( + fontSize: 24, + fontWeight: NamedFontWeight.extraBold, + color: BrandColors.headlineColor, +); + +final onboardingTitle = GoogleFonts.inter( fontSize: 30, fontWeight: NamedFontWeight.extraBold, color: BrandColors.headlineColor, @@ -40,6 +46,8 @@ final body2Style = defaultTextStyle.copyWith( color: BrandColors.textColor2, ); +final mediumStyle = defaultTextStyle.copyWith(fontSize: 13, height: 1.53); + final smallStyle = defaultTextStyle.copyWith(fontSize: 11, height: 1.45); final linkStyle = defaultTextStyle.copyWith(color: BrandColors.blue); diff --git a/lib/logic/api_maps/api_map.dart b/lib/logic/api_maps/api_map.dart new file mode 100644 index 0000000000..53c345245c --- /dev/null +++ b/lib/logic/api_maps/api_map.dart @@ -0,0 +1,11 @@ +import 'package:dio/dio.dart'; + +abstract class ApiMap { + String rootAddress; + + Dio client = Dio(); + + void close() { + client.close(); + } +} diff --git a/lib/logic/api_maps/cloud_flare.dart b/lib/logic/api_maps/cloud_flare.dart new file mode 100644 index 0000000000..70b0d555e5 --- /dev/null +++ b/lib/logic/api_maps/cloud_flare.dart @@ -0,0 +1,127 @@ +import 'dart:io'; +import 'package:dio/dio.dart'; +import 'package:selfprivacy/logic/api_maps/api_map.dart'; +import 'package:selfprivacy/logic/models/cloudflare_domain.dart'; +import 'package:selfprivacy/logic/models/dns_records.dart'; + +class CloudflareApi extends ApiMap { + CloudflareApi([String token]) { + if (token != null) { + client.options = BaseOptions(headers: {'Authorization': 'Bearer $token'}); + } + } + + @override + String rootAddress = 'https://api.cloudflare.com/client/v4'; + + Future isValid(String token) async { + var url = '$rootAddress/user/tokens/verify'; + var options = Options( + headers: {'Authorization': 'Bearer $token'}, + validateStatus: (status) { + return status == HttpStatus.ok || status == HttpStatus.unauthorized; + }, + ); + + Response response = await client.get(url, options: options); + + if (response.statusCode == HttpStatus.ok) { + return true; + } else if (response.statusCode == HttpStatus.unauthorized) { + return false; + } else { + throw Exception('something bad happend'); + } + } + + Future getZoneId(String token, String domain) async { + var url = '$rootAddress/zones'; + + var options = Options( + headers: {'Authorization': 'Bearer $token'}, + validateStatus: (status) { + return status == HttpStatus.ok || status == HttpStatus.forbidden; + }, + ); + + Response response = await client.get( + url, + options: options, + queryParameters: {'name': domain}, + ); + + try { + return response.data['result'][0]['id']; + } catch (error) { + return null; + } + } + + Future createMultipleDnsRecords({ + String ip4, + CloudFlareDomain cloudFlareDomain, + }) async { + var domainName = cloudFlareDomain.name; + var domainZoneId = cloudFlareDomain.zoneId; + + var domainA = DnsRecords(type: 'A', name: domainName, content: ip4); + var apiA = DnsRecords(type: 'A', name: 'api', content: ip4); + var cloudA = DnsRecords(type: 'A', name: 'cloud', content: ip4); + var gitA = DnsRecords(type: 'A', name: 'git', content: ip4); + var meetA = DnsRecords(type: 'A', name: 'meet', content: ip4); + var passwordA = DnsRecords(type: 'A', name: 'password', content: ip4); + var socialA = DnsRecords(type: 'A', name: 'social', content: ip4); + var mx = DnsRecords(type: 'MX', name: '@', content: domainName); + + var txt1 = DnsRecords( + type: 'TXT', + name: '_dmarc', + content: 'v=DMARC1; p=none', + ttl: 18000, + ); + + var txt2 = DnsRecords( + type: 'TXT', + name: cloudFlareDomain.name, + content: 'v=spf1 a mx ip4:$ip4 -all', + ttl: 18000, + ); + + var listDnsRecords = [ + domainA, + apiA, + cloudA, + gitA, + meetA, + passwordA, + socialA, + mx, + txt1, + txt2 + ]; + + var allFutures = []; + + for (var record in listDnsRecords) { + var url = '$rootAddress/zones/$domainZoneId/dns_records'; + + allFutures.add( + client.post( + url, + data: record.toJson(), + ), + ); + } + + await Future.wait(allFutures); + } + + // createSDKIM(String dkim) { + // var txt3 = DnsRecords( + // type: 'TXT', + // name: 'selector._domainkey', + // content: dkim, + // ttl: 18000, + // ); + // } +} diff --git a/lib/logic/api_maps/hetzner.dart b/lib/logic/api_maps/hetzner.dart new file mode 100644 index 0000000000..a14027c18d --- /dev/null +++ b/lib/logic/api_maps/hetzner.dart @@ -0,0 +1,64 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:selfprivacy/logic/api_maps/api_map.dart'; +import 'package:selfprivacy/logic/models/server_details.dart'; +import 'package:selfprivacy/logic/models/user.dart'; + +class HetznerApi extends ApiMap { + HetznerApi([String token]) { + if (token != null) { + client.options = BaseOptions(headers: {'Authorization': 'Bearer $token'}); + } + } + + @override + String rootAddress = 'https://api.hetzner.cloud/v1/servers'; + + Future isValid(String token) async { + var options = Options( + headers: {'Authorization': 'Bearer $token'}, + validateStatus: (status) { + return status == HttpStatus.ok || status == HttpStatus.unauthorized; + }, + ); + + Response response = await client.get(rootAddress, options: options); + + if (response.statusCode == HttpStatus.ok) { + return true; + } else if (response.statusCode == HttpStatus.unauthorized) { + return false; + } else { + throw Exception('something bad happend'); + } + } + + Future createServer({ + @required User rootUser, + @required String domainName, + }) async { + var data = { + "name": "selfprivacy-server", + "server_type": "cx11", + "start_after_create": true, + "image": "ubuntu-20.04", + "ssh_keys": [], + "volumes": [], + "networks": [], + "user_data": + "#cloud-config\nruncmd:\n- curl https://git.selfprivacy.org/ilchub/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-20.09 DOMAIN=$domainName USER=${rootUser.login} PASSWORD=${rootUser.password} HASHED_PASSWORD=${rootUser.hashPassword} bash 2>&1 | tee /tmp/infect.log \nruncmd:\n- curl https://git.selfprivacy.org/ilchub/selfprivacy-nixos-infect/raw/branch/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-20.09 DOMAIN=$domainName USER=${rootUser.login} PASSWORD=${rootUser.password} HASHED_PASSWORD=${rootUser.hashPassword} bash 2>&1 | tee /tmp/infect.log", + }; + Response response = await client.post( + rootAddress, + data: data, + ); + + return HetznerServerDetails( + id: response.data['server']['id'], + ip4: response.data['server']['public_net']['ipv4']['ip'], + serverInitializaionDateTime: DateTime.now(), + ); + } +} diff --git a/lib/logic/cubit/app_config/app_config_cubit.dart b/lib/logic/cubit/app_config/app_config_cubit.dart new file mode 100644 index 0000000000..56ca79cb53 --- /dev/null +++ b/lib/logic/cubit/app_config/app_config_cubit.dart @@ -0,0 +1,86 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:hive/hive.dart'; +import 'package:selfprivacy/config/hive_config.dart'; +import 'package:selfprivacy/logic/api_maps/cloud_flare.dart'; +import 'package:selfprivacy/logic/api_maps/hetzner.dart'; +import 'package:selfprivacy/logic/models/cloudflare_domain.dart'; +import 'package:selfprivacy/logic/models/server_details.dart'; +import 'package:selfprivacy/logic/models/user.dart'; + +part 'app_config_state.dart'; + +class AppConfigCubit extends Cubit { + AppConfigCubit() : super(InitialAppConfigState()); + + Box box = Hive.box(BNames.appConfig); + + void load() { + emit( + state.copyWith( + hetznerKey: box.get(BNames.hetznerKey), + cloudFlareKey: box.get(BNames.cloudFlareKey), + domain: box.get(BNames.domain), + rootUser: box.get(BNames.rootUser), + hetznerServer: box.get(BNames.server), + isDnsCheckedAndDkimSet: box.get(BNames.isDnsCheckedAndDkimSet), + ), + ); + } + + void reset() { + box.clear(); + emit(InitialAppConfigState()); + } + + void setHetznerKey(String key) { + box.put(BNames.hetznerKey, key); + emit(state.copyWith(hetznerKey: key)); + } + + void setCloudFlare(String cloudFlareKey) { + box.put(BNames.cloudFlareKey, cloudFlareKey); + emit(state.copyWith(cloudFlareKey: cloudFlareKey)); + } + + void setDomain(CloudFlareDomain domain) { + box.put(BNames.domain, domain); + emit(state.copyWith(domain: domain)); + } + + void setRootUser(User rootUser) { + box.put(BNames.rootUser, rootUser); + emit(state.copyWith(rootUser: rootUser)); + } + + void setIsDnsCheckedAndDkimSet() { + box.put(BNames.isDnsCheckedAndDkimSet, true); + emit(state.copyWith(isDnsCheckedAndDkimSet: true)); + } + + void createServer() async { + emit(state.copyWith(isLoading: true)); + var hetznerApi = HetznerApi(state.hetznerKey); + var cloudflareApi = CloudflareApi(state.cloudFlareKey); + + var serverDetails = await hetznerApi.createServer( + rootUser: state.rootUser, + domainName: state.cloudFlareDomain.name, + ); + + cloudflareApi + .createMultipleDnsRecords( + ip4: serverDetails.ip4, + cloudFlareDomain: state.cloudFlareDomain, + ) + .then((_) => cloudflareApi.close()); + await box.put(BNames.server, serverDetails); + + hetznerApi.close(); + + emit(state.copyWith( + isLoading: false, + hetznerServer: serverDetails, + )); + } +} diff --git a/lib/logic/cubit/app_config/app_config_state.dart b/lib/logic/cubit/app_config/app_config_state.dart new file mode 100644 index 0000000000..9cb4da35c5 --- /dev/null +++ b/lib/logic/cubit/app_config/app_config_state.dart @@ -0,0 +1,76 @@ +part of 'app_config_cubit.dart'; + +class AppConfigState extends Equatable { + const AppConfigState({ + this.hetznerKey, + this.cloudFlareKey, + this.cloudFlareDomain, + this.rootUser, + this.server, + this.isDnsCheckedAndDkimSet = false, + this.isLoading = false, + }); + + @override + List get props => [ + hetznerKey, + cloudFlareKey, + cloudFlareDomain, + rootUser, + server, + isDnsCheckedAndDkimSet, + isLoading, + ]; + + final String hetznerKey; + final String cloudFlareKey; + final CloudFlareDomain cloudFlareDomain; + final User rootUser; + final HetznerServerDetails server; + final bool isDnsCheckedAndDkimSet; + + final isLoading; + + AppConfigState copyWith({ + String hetznerKey, + String cloudFlareKey, + CloudFlareDomain domain, + User rootUser, + HetznerServerDetails hetznerServer, + bool isDnsCheckedAndDkimSet, + bool isLoading, + DateTime serverInitStart, + }) => + AppConfigState( + hetznerKey: hetznerKey ?? this.hetznerKey, + cloudFlareKey: cloudFlareKey ?? this.cloudFlareKey, + cloudFlareDomain: domain ?? this.cloudFlareDomain, + rootUser: rootUser ?? this.rootUser, + server: hetznerServer ?? this.server, + isDnsCheckedAndDkimSet: isDnsCheckedAndDkimSet ?? this.isDnsCheckedAndDkimSet, + isLoading: isLoading ?? this.isLoading, + ); + + bool get isHetznerFilled => hetznerKey != null; + bool get isCloudFlareFilled => cloudFlareKey != null; + bool get isDomainFilled => cloudFlareDomain != null; + bool get isUserFilled => rootUser != null; + bool get isServerFilled => server != null; + + bool get isFullyInitilized => _fulfilementList.every((el) => el); + + int get progress => _fulfilementList.where((el) => el).length; + + List get _fulfilementList => [ + isHetznerFilled, + isCloudFlareFilled, + isDomainFilled, + isUserFilled, + isServerFilled, + isDnsCheckedAndDkimSet, + ]; +} + +class InitialAppConfigState extends AppConfigState { + InitialAppConfigState() : super(); +} diff --git a/lib/logic/cubit/app_settings/app_settings_cubit.dart b/lib/logic/cubit/app_settings/app_settings_cubit.dart index a14f1577e9..9435b3c4c5 100644 --- a/lib/logic/cubit/app_settings/app_settings_cubit.dart +++ b/lib/logic/cubit/app_settings/app_settings_cubit.dart @@ -1,18 +1,44 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/widgets.dart'; +import 'package:hive/hive.dart'; +import 'package:selfprivacy/config/hive_config.dart'; export 'package:provider/provider.dart'; part 'app_settings_state.dart'; class AppSettingsCubit extends Cubit { AppSettingsCubit({ - bool isDarkModeOn, + @required bool isDarkModeOn, + @required bool isOnbordingShowing, }) : super( - AppSettingsState(isDarkModeOn: isDarkModeOn), + AppSettingsState( + isDarkModeOn: isDarkModeOn, + isOnbordingShowing: isOnbordingShowing, + ), ); - void update({@required bool isDarkModeOn}) { - emit(AppSettingsState(isDarkModeOn: isDarkModeOn)); + Box box = Hive.box(BNames.appSettings); + + void load() { + bool isDarkModeOn = box.get(BNames.isDarkModeOn); + bool isOnbordingShowing = box.get(BNames.isOnbordingShowing); + + emit(state.copyWith( + isDarkModeOn: isDarkModeOn, + isOnbordingShowing: isOnbordingShowing, + )); + } + + void updateDarkMode({@required bool isDarkModeOn}) { + box.put(BNames.isDarkModeOn, isDarkModeOn); + + emit(state.copyWith(isDarkModeOn: isDarkModeOn)); + } + + void turnOffOnboarding() { + box.put(BNames.isOnbordingShowing, false); + + emit(state.copyWith(isOnbordingShowing: false)); } } diff --git a/lib/logic/cubit/app_settings/app_settings_state.dart b/lib/logic/cubit/app_settings/app_settings_state.dart index 1ad6840474..023ad2d03f 100644 --- a/lib/logic/cubit/app_settings/app_settings_state.dart +++ b/lib/logic/cubit/app_settings/app_settings_state.dart @@ -3,10 +3,18 @@ part of 'app_settings_cubit.dart'; class AppSettingsState extends Equatable { const AppSettingsState({ @required this.isDarkModeOn, + @required this.isOnbordingShowing, }); final bool isDarkModeOn; + final bool isOnbordingShowing; + + AppSettingsState copyWith({isDarkModeOn, isOnbordingShowing}) => + AppSettingsState( + isDarkModeOn: isDarkModeOn ?? this.isDarkModeOn, + isOnbordingShowing: isOnbordingShowing ?? this.isOnbordingShowing, + ); @override - List get props => [isDarkModeOn]; + List get props => [isDarkModeOn, isOnbordingShowing]; } diff --git a/lib/logic/cubit/forms/initializing/cloudflare_form_cubit.dart b/lib/logic/cubit/forms/initializing/cloudflare_form_cubit.dart index e69de29bb2..91d12ff54e 100644 --- a/lib/logic/cubit/forms/initializing/cloudflare_form_cubit.dart +++ b/lib/logic/cubit/forms/initializing/cloudflare_form_cubit.dart @@ -0,0 +1,52 @@ +import 'dart:async'; + +import 'package:cubit_form/cubit_form.dart'; +import 'package:selfprivacy/logic/api_maps/cloud_flare.dart'; +import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; +import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart'; + +class CloudFlareFormCubit extends FormCubit { + CloudflareApi apiClient = CloudflareApi(); + + CloudFlareFormCubit(this.initializingCubit) { + var regExp = RegExp(r"\s+|[!$%^&*()_@+|~=`{}\[\]:<>?,.\/]"); + apiKey = FieldCubit( + initalValue: '', + validations: [ + RequiredStringValidation('required'), + ValidationModel( + (s) => regExp.hasMatch(s), 'invalid key format'), + LegnthStringValidationWithLenghShowing(40, 'length is [] shoud be 40') + ], + ); + + super.setFields([apiKey]); + } + + @override + FutureOr onSubmit() async { + initializingCubit.setCloudFlare(apiKey.state.value); + } + + final AppConfigCubit initializingCubit; + + FieldCubit apiKey; + + @override + FutureOr asyncValidation() async { + var isKeyValid = await apiClient.isValid(apiKey.state.value); + + if (!isKeyValid) { + apiKey.setError('bad key'); + return false; + } + return true; + } + + @override + Future close() async { + apiClient.close(); + + return super.close(); + } +} diff --git a/lib/logic/cubit/forms/initializing/domain_form_cubit.dart b/lib/logic/cubit/forms/initializing/domain_form_cubit.dart index e69de29bb2..49de42f383 100644 --- a/lib/logic/cubit/forms/initializing/domain_form_cubit.dart +++ b/lib/logic/cubit/forms/initializing/domain_form_cubit.dart @@ -0,0 +1,60 @@ +import 'dart:async'; + +import 'package:cubit_form/cubit_form.dart'; +import 'package:selfprivacy/logic/api_maps/cloud_flare.dart'; +import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; +import 'package:selfprivacy/logic/models/cloudflare_domain.dart'; + +class DomainFormCubit extends FormCubit { + CloudflareApi apiClient = CloudflareApi(); + + DomainFormCubit(this.initializingCubit) { + var regExp = + RegExp(r"^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}"); + domainName = FieldCubit( + initalValue: '', + validations: [ + RequiredStringValidation('required'), + ValidationModel( + (s) => !regExp.hasMatch(s), 'invalid domain format'), + ], + ); + + super.setFields([domainName]); + } + + @override + FutureOr onSubmit() async { + var domain = CloudFlareDomain( + name: domainName.state.value, + zoneId: zoneId, + ); + initializingCubit.setDomain(domain); + } + + final AppConfigCubit initializingCubit; + + FieldCubit domainName; + String zoneId; + + @override + FutureOr asyncValidation() async { + var key = initializingCubit.state.cloudFlareKey; + + var zoneId = await apiClient.getZoneId(key, domainName.state.value); + + if (zoneId == null) { + domainName.setError('Domain not in the list'); + return false; + } + this.zoneId = zoneId; + return true; + } + + @override + Future close() async { + apiClient.close(); + + return super.close(); + } +} diff --git a/lib/logic/cubit/forms/initializing/hetzner_form_cubit.dart b/lib/logic/cubit/forms/initializing/hetzner_form_cubit.dart index 0a62d7151d..657147aa5c 100644 --- a/lib/logic/cubit/forms/initializing/hetzner_form_cubit.dart +++ b/lib/logic/cubit/forms/initializing/hetzner_form_cubit.dart @@ -1,18 +1,22 @@ import 'dart:async'; import 'package:cubit_form/cubit_form.dart'; -import 'package:selfprivacy/logic/cubit/initializing/initializing_cubit.dart'; +import 'package:selfprivacy/logic/api_maps/hetzner.dart'; +import 'package:selfprivacy/logic/cubit/forms/validations/validations.dart'; +import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; class HetznerFormCubit extends FormCubit { + HetznerApi apiClient = HetznerApi(); + HetznerFormCubit(this.initializingCubit) { - var regExp = RegExp(r"\s+|[-!$%^&*()_@+|~=`{}\[\]:" ";<>?,.\/]"); + var regExp = RegExp(r"\s+|[-!$%^&*()_@+|~=`{}\[\]:<>?,.\/]"); apiKey = FieldCubit( initalValue: '', validations: [ RequiredStringValidation('required'), ValidationModel( (s) => regExp.hasMatch(s), 'invalid key format'), - LegnthStringValidation(11, 'length is [] shoud be 11') + LegnthStringValidationWithLenghShowing(64, 'length is [] shoud be 64') ], ); @@ -21,24 +25,28 @@ class HetznerFormCubit extends FormCubit { @override FutureOr onSubmit() async { - print(apiKey.state.value); - await Future.delayed(const Duration(milliseconds: 300)); - // initializingCubit.setHetznerKey(apiKey.state.value); + initializingCubit.setHetznerKey(apiKey.state.value); } - final InitializingCubit initializingCubit; + final AppConfigCubit initializingCubit; FieldCubit apiKey; -} - -class LegnthStringValidation extends ValidationModel { - LegnthStringValidation(int length, String errorText) - : super((n) => n.length != length, errorText); @override - String check(String val) { - var length = val.length; - var errorMassage = this.errorMassage.replaceAll("[]", length.toString()); - return test(val) ? errorMassage : null; + FutureOr asyncValidation() async { + var isKeyValid = await apiClient.isValid(apiKey.state.value); + + if (!isKeyValid) { + apiKey.setError('bad key'); + return false; + } + return true; + } + + @override + Future close() async { + apiClient.close(); + + return super.close(); } } diff --git a/lib/logic/cubit/forms/initializing/user_form_cubit.dart b/lib/logic/cubit/forms/initializing/user_form_cubit.dart index e69de29bb2..47ea136504 100644 --- a/lib/logic/cubit/forms/initializing/user_form_cubit.dart +++ b/lib/logic/cubit/forms/initializing/user_form_cubit.dart @@ -0,0 +1,56 @@ +import 'dart:async'; + +import 'package:cubit_form/cubit_form.dart'; +import 'package:selfprivacy/logic/api_maps/hetzner.dart'; +import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; +import 'package:selfprivacy/logic/models/user.dart'; + +class UserFormCubit extends FormCubit { + HetznerApi apiClient = HetznerApi(); + + UserFormCubit(this.initializingCubit) { + var userRegExp = RegExp(r"\W"); + var passwordRegExp = RegExp(r"[\n\r\s]+"); + + userName = FieldCubit( + initalValue: '', + validations: [ + RequiredStringValidation('required'), + ValidationModel( + (s) => userRegExp.hasMatch(s), 'invalid format'), + ], + ); + + password = FieldCubit( + initalValue: '', + validations: [ + RequiredStringValidation('required'), + ValidationModel( + (s) => passwordRegExp.hasMatch(s), 'invalid format'), + ], + ); + + super.setFields([userName, password]); + } + + @override + FutureOr onSubmit() async { + var user = User( + login: userName.state.value, + password: password.state.value, + ); + initializingCubit.setRootUser(user); + } + + final AppConfigCubit initializingCubit; + + FieldCubit userName; + FieldCubit password; + + @override + Future close() async { + apiClient.close(); + + return super.close(); + } +} diff --git a/lib/logic/cubit/forms/user/user.dart b/lib/logic/cubit/forms/user/user.dart new file mode 100644 index 0000000000..b51c5c4830 --- /dev/null +++ b/lib/logic/cubit/forms/user/user.dart @@ -0,0 +1,51 @@ +import 'dart:async'; + +import 'package:cubit_form/cubit_form.dart'; +import 'package:selfprivacy/logic/cubit/users/users_cubit.dart'; +import 'package:selfprivacy/logic/models/user.dart'; + +class CloudFlareFormCubit extends FormCubit { + CloudFlareFormCubit({ + this.userCubit, + User user, + }) { + var isEdit = user != null; + + var userRegExp = RegExp(r"\W"); + var passwordRegExp = RegExp(r"[\n\r\s]+"); + + login = FieldCubit( + initalValue: isEdit ? user.login : '', + validations: [ + RequiredStringValidation('required'), + ValidationModel( + (s) => userRegExp.hasMatch(s), 'invalid format'), + ], + ); + + password = FieldCubit( + initalValue: isEdit ? user.password : '', + validations: [ + RequiredStringValidation('required'), + ValidationModel( + (s) => passwordRegExp.hasMatch(s), 'invalid format'), + ], + ); + + super.setFields([login, password]); + } + + @override + FutureOr onSubmit() { + var user = User( + login: login.state.value, + password: password.state.value, + ); + userCubit.add(user); + } + + FieldCubit login; + FieldCubit password; + + UsersCubit userCubit; +} diff --git a/lib/logic/cubit/forms/validations/validations.dart b/lib/logic/cubit/forms/validations/validations.dart new file mode 100644 index 0000000000..bf39f78774 --- /dev/null +++ b/lib/logic/cubit/forms/validations/validations.dart @@ -0,0 +1,13 @@ +import 'package:cubit_form/cubit_form.dart'; + +class LegnthStringValidationWithLenghShowing extends ValidationModel { + LegnthStringValidationWithLenghShowing(int length, String errorText) + : super((n) => n.length != length, errorText); + + @override + String check(String val) { + var length = val.length; + var errorMassage = this.errorMassage.replaceAll("[]", length.toString()); + return test(val) ? errorMassage : null; + } +} diff --git a/lib/logic/cubit/initializing/initializing_cubit.dart b/lib/logic/cubit/initializing/initializing_cubit.dart deleted file mode 100644 index 0fe6bcd978..0000000000 --- a/lib/logic/cubit/initializing/initializing_cubit.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:bloc/bloc.dart'; -import 'package:equatable/equatable.dart'; -import 'package:selfprivacy/logic/models/config.dart'; -import 'package:selfprivacy/logic/models/user.dart'; - -part 'initializing_state.dart'; - -class InitializingCubit extends Cubit { - InitializingCubit() : super(InitialInitializingState()); - - void setHetznerKey(String key) { - var newCofig = state.appConfig.copyWith(hatzner: key); - emit(InitializingState(newCofig)); - } - - void setCloudFlare(String cloudFlareKey) { - var newCofig = state.appConfig.copyWith(cloudFlare: cloudFlareKey); - emit(InitializingState(newCofig)); - } - - void setDomain(String domain) { - var newCofig = state.appConfig.copyWith(domain: domain); - emit(InitializingState(newCofig)); - } - - void setRootUser(User rootUser) { - var newCofig = state.appConfig.copyWith(rootUser: rootUser); - emit(InitializingState(newCofig)); - } -} diff --git a/lib/logic/cubit/initializing/initializing_state.dart b/lib/logic/cubit/initializing/initializing_state.dart deleted file mode 100644 index 7827987d66..0000000000 --- a/lib/logic/cubit/initializing/initializing_state.dart +++ /dev/null @@ -1,26 +0,0 @@ -part of 'initializing_cubit.dart'; - -class InitializingState extends Equatable { - const InitializingState(this.appConfig); - - final AppConfig appConfig; - - @override - List get props => [appConfig]; - - bool get isHatznerFilled => appConfig.hatzner != null; - bool get isCloudFlareFilled => appConfig.cloudFlare != null; - bool get isDomainFilled => appConfig.domain != null; - bool get isUserFilled => appConfig.rootUser != null; - - bool get isFullyInitilized => _fulfilementList.every((el) => el); - - int get progress => _fulfilementList.where((el) => el).length; - - List get _fulfilementList => - [isHatznerFilled, isCloudFlareFilled, isDomainFilled, isUserFilled]; -} - -class InitialInitializingState extends InitializingState { - InitialInitializingState() : super(AppConfig.empty()); -} diff --git a/lib/logic/cubit/users/users_cubit.dart b/lib/logic/cubit/users/users_cubit.dart index 6febf023b7..6dcdd371d5 100644 --- a/lib/logic/cubit/users/users_cubit.dart +++ b/lib/logic/cubit/users/users_cubit.dart @@ -1,13 +1,12 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:selfprivacy/logic/models/user.dart'; -import 'package:selfprivacy/utils/password_generator.dart'; export 'package:provider/provider.dart'; part 'users_state.dart'; class UsersCubit extends Cubit { - UsersCubit() : super(UsersState(initMockUsers)); + UsersCubit() : super(UsersState([])); void add(User user) { var users = state.users; @@ -24,20 +23,20 @@ class UsersCubit extends Cubit { } } -final initMockUsers = [ - User(login: 'Heartbreaking.Goose', password: genPass()), - User(login: 'Alma.lawson', password: genPass()), - User(login: 'Bee.gees', password: genPass()), - User(login: 'Bim.jennings', password: genPass()), - User(login: 'Debra.holt', password: genPass()), - User(login: 'Georgia.young', password: genPass()), - User(login: 'Kenzi.lawson', password: genPass()), - User(login: 'Le.jennings', password: genPass()), - User(login: 'Kirill.Zh', password: genPass()), - User(login: 'Tina.Bolton', password: genPass()), - User(login: 'Rebekah.Lynn', password: genPass()), - User(login: 'Aleena.Armstrong', password: genPass()), - User(login: 'Rosemary.Williams', password: genPass()), - User(login: 'Sullivan.Nixon', password: genPass()), - User(login: 'Aleena.Armstrong', password: genPass()), -]; +// final initMockUsers = [ +// User(login: 'Heartbreaking.Goose', password: genPass()), +// User(login: 'Alma.lawson', password: genPass()), +// User(login: 'Bee.gees', password: genPass()), +// User(login: 'Bim.jennings', password: genPass()), +// User(login: 'Debra.holt', password: genPass()), +// User(login: 'Georgia.young', password: genPass()), +// User(login: 'Kenzi.lawson', password: genPass()), +// User(login: 'Le.jennings', password: genPass()), +// User(login: 'Kirill.Zh', password: genPass()), +// User(login: 'Tina.Bolton', password: genPass()), +// User(login: 'Rebekah.Lynn', password: genPass()), +// User(login: 'Aleena.Armstrong', password: genPass()), +// User(login: 'Rosemary.Williams', password: genPass()), +// User(login: 'Sullivan.Nixon', password: genPass()), +// User(login: 'Aleena.Armstrong', password: genPass()), +// ]; diff --git a/lib/logic/cubit/users/users_state.dart b/lib/logic/cubit/users/users_state.dart index a7412631d9..88c56146ec 100644 --- a/lib/logic/cubit/users/users_state.dart +++ b/lib/logic/cubit/users/users_state.dart @@ -7,4 +7,6 @@ class UsersState extends Equatable { @override List get props => users; + + bool get isEmpty => users.isEmpty; } diff --git a/lib/logic/models/cloudflare_domain.dart b/lib/logic/models/cloudflare_domain.dart new file mode 100644 index 0000000000..0cc24781aa --- /dev/null +++ b/lib/logic/models/cloudflare_domain.dart @@ -0,0 +1,19 @@ +import 'package:hive/hive.dart'; + +part 'cloudflare_domain.g.dart'; + +@HiveType(typeId: 3) +class CloudFlareDomain { + CloudFlareDomain({this.name, this.zoneId}); + + @HiveField(0) + final String name; + + @HiveField(1) + final String zoneId; + + @override + String toString() { + return '$name: $zoneId'; + } +} diff --git a/lib/logic/models/cloudflare_domain.g.dart b/lib/logic/models/cloudflare_domain.g.dart new file mode 100644 index 0000000000..c1dee8bdd6 --- /dev/null +++ b/lib/logic/models/cloudflare_domain.g.dart @@ -0,0 +1,44 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'cloudflare_domain.dart'; + +// ************************************************************************** +// TypeAdapterGenerator +// ************************************************************************** + +class CloudFlareDomainAdapter extends TypeAdapter { + @override + final int typeId = 3; + + @override + CloudFlareDomain read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return CloudFlareDomain( + name: fields[0] as String, + zoneId: fields[1] as String, + ); + } + + @override + void write(BinaryWriter writer, CloudFlareDomain obj) { + writer + ..writeByte(2) + ..writeByte(0) + ..write(obj.name) + ..writeByte(1) + ..write(obj.zoneId); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is CloudFlareDomainAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/lib/logic/models/config.dart b/lib/logic/models/config.dart deleted file mode 100644 index 82552241e5..0000000000 --- a/lib/logic/models/config.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:selfprivacy/logic/models/user.dart'; - -class AppConfig extends Equatable { - const AppConfig({ - this.hatzner, - this.cloudFlare, - this.domain, - this.rootUser, - }); - - final String hatzner; - final String cloudFlare; - final String domain; - final User rootUser; - - factory AppConfig.empty() { - return AppConfig(); - } - - AppConfig copyWith({ - hatzner, - cloudFlare, - domain, - rootUser, - }) => - AppConfig( - hatzner: hatzner ?? this.hatzner, - cloudFlare: cloudFlare ?? this.cloudFlare, - domain: domain ?? this.domain, - rootUser: rootUser ?? this.rootUser, - ); - - @override - List get props => [hatzner, cloudFlare, domain, rootUser]; -} diff --git a/lib/logic/models/dns_records.dart b/lib/logic/models/dns_records.dart new file mode 100644 index 0000000000..748ec76358 --- /dev/null +++ b/lib/logic/models/dns_records.dart @@ -0,0 +1,25 @@ +import 'package:flutter/foundation.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'dns_records.g.dart'; + +@JsonSerializable(createToJson: true, createFactory: false) +class DnsRecords { + DnsRecords({ + @required this.type, + @required this.name, + @required this.content, + this.ttl = 3600, + this.priority = 10, + this.proxied = false, + }); + + final String type; + final String name; + final String content; + final int ttl; + final int priority; + final bool proxied; + + toJson() => _$DnsRecordsToJson(this); +} diff --git a/lib/logic/models/dns_records.g.dart b/lib/logic/models/dns_records.g.dart new file mode 100644 index 0000000000..315cb447e1 --- /dev/null +++ b/lib/logic/models/dns_records.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'dns_records.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Map _$DnsRecordsToJson(DnsRecords instance) => + { + 'type': instance.type, + 'name': instance.name, + 'content': instance.content, + 'ttl': instance.ttl, + 'priority': instance.priority, + 'proxied': instance.proxied, + }; diff --git a/lib/logic/models/server_details.dart b/lib/logic/models/server_details.dart new file mode 100644 index 0000000000..c628f07324 --- /dev/null +++ b/lib/logic/models/server_details.dart @@ -0,0 +1,24 @@ +import 'package:flutter/widgets.dart'; +import 'package:hive/hive.dart'; + +part 'server_details.g.dart'; + +@HiveType(typeId: 2) +class HetznerServerDetails { + HetznerServerDetails({ + @required this.ip4, + @required this.id, + @required this.serverInitializaionDateTime, + }); + + @HiveField(0) + final String ip4; + + @HiveField(1) + final int id; + + @HiveField(2) + final DateTime serverInitializaionDateTime; + + String toString() => id.toString(); +} diff --git a/lib/logic/models/server_details.g.dart b/lib/logic/models/server_details.g.dart new file mode 100644 index 0000000000..a51e314067 --- /dev/null +++ b/lib/logic/models/server_details.g.dart @@ -0,0 +1,47 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'server_details.dart'; + +// ************************************************************************** +// TypeAdapterGenerator +// ************************************************************************** + +class HetznerServerDetailsAdapter extends TypeAdapter { + @override + final int typeId = 2; + + @override + HetznerServerDetails read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return HetznerServerDetails( + ip4: fields[0] as String, + id: fields[1] as int, + serverInitializaionDateTime: fields[2] as DateTime, + ); + } + + @override + void write(BinaryWriter writer, HetznerServerDetails obj) { + writer + ..writeByte(3) + ..writeByte(0) + ..write(obj.ip4) + ..writeByte(1) + ..write(obj.id) + ..writeByte(2) + ..write(obj.serverInitializaionDateTime); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is HetznerServerDetailsAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/lib/logic/models/user.dart b/lib/logic/models/user.dart index 4a96cee614..3c37a356df 100644 --- a/lib/logic/models/user.dart +++ b/lib/logic/models/user.dart @@ -3,18 +3,32 @@ import 'dart:ui'; import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; import 'package:selfprivacy/utils/color_utils.dart'; +import 'package:hive/hive.dart'; +import 'package:selfprivacy/utils/crypto.dart'; +part 'user.g.dart'; + +@HiveType(typeId: 1) class User extends Equatable { User({ @required this.login, @required this.password, }); + @HiveField(0) final String login; + + @HiveField(1) final String password; @override List get props => [login, password]; Color get color => stringToColor(login); + + String get hashPassword => convertToSha512Hash(password); + + String toString() { + return login; + } } diff --git a/lib/logic/models/user.g.dart b/lib/logic/models/user.g.dart new file mode 100644 index 0000000000..796ea5ddcc --- /dev/null +++ b/lib/logic/models/user.g.dart @@ -0,0 +1,44 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user.dart'; + +// ************************************************************************** +// TypeAdapterGenerator +// ************************************************************************** + +class UserAdapter extends TypeAdapter { + @override + final int typeId = 1; + + @override + User read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return User( + login: fields[0] as String, + password: fields[1] as String, + ); + } + + @override + void write(BinaryWriter writer, User obj) { + writer + ..writeByte(2) + ..writeByte(0) + ..write(obj.login) + ..writeByte(1) + ..write(obj.password); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is UserAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/lib/main.dart b/lib/main.dart index 61f8194e90..731665bc28 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,15 +1,18 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:selfprivacy/config/hive_config.dart'; +import 'package:selfprivacy/ui/pages/initializing/initializing.dart'; import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:selfprivacy/ui/pages/rootRoute.dart'; - import 'config/bloc_config.dart'; import 'config/brand_theme.dart'; import 'config/localization.dart'; import 'logic/cubit/app_settings/app_settings_cubit.dart'; -void main() { +void main() async { + await HiveConfig.init(); + WidgetsFlutterBinding.ensureInitialized(); runApp( @@ -21,11 +24,11 @@ void main() { ); } -var _showOnbording = true; - class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { + var appSettings = context.watch().state; + return AnnotatedRegion( value: SystemUiOverlayStyle.light, // Manually changnig appbar color child: MaterialApp( @@ -34,10 +37,10 @@ class MyApp extends StatelessWidget { locale: context.locale, debugShowCheckedModeBanner: false, title: 'SelfPrivacy', - theme: context.watch().state.isDarkModeOn - ? darkTheme - : ligtTheme, - home: _showOnbording ? OnboardingPage() : RootPage(), + theme: appSettings.isDarkModeOn ? darkTheme : ligtTheme, + home: appSettings.isOnbordingShowing + ? OnboardingPage(nextPage: InitializingPage()) + : RootPage(), ), ); } diff --git a/lib/ui/components/brand_card/brand_card.dart b/lib/ui/components/brand_card/brand_card.dart index 6908b36339..a30ef5b15d 100644 --- a/lib/ui/components/brand_card/brand_card.dart +++ b/lib/ui/components/brand_card/brand_card.dart @@ -1,21 +1,18 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_colors.dart'; -import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/utils/extensions/elevation_extension.dart'; class BrandCard extends StatelessWidget { const BrandCard({ Key key, this.child, - this.isBlocked = false, }) : super(key: key); final Widget child; - final bool isBlocked; @override Widget build(BuildContext context) { - Widget res = Container( + return Container( margin: EdgeInsets.only(bottom: 30), decoration: BoxDecoration( color: Theme.of(context).brightness == Brightness.dark @@ -29,44 +26,5 @@ class BrandCard extends StatelessWidget { ), child: child, ); - - if (!isBlocked) { - return res; - } - - return IgnorePointer( - child: Stack( - children: [ - ColorFiltered( - colorFilter: ColorFilter.mode( - Colors.white, - BlendMode.saturation, - ), - child: res, - ), - Positioned( - top: 0, - left: 0, - right: 0, - bottom: 0, - child: Container( - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: Colors.white.withOpacity(0.8), - ), - padding: EdgeInsets.all(10), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - BrandText.h3('Blocked'), - BrandText.h4('finish initializing first') - ], - ), - ), - ) - ], - ), - ); } } diff --git a/lib/ui/components/brand_tab_bar/brand_tab_bar.dart b/lib/ui/components/brand_tab_bar/brand_tab_bar.dart index e06600a6f0..544dc6db65 100644 --- a/lib/ui/components/brand_tab_bar/brand_tab_bar.dart +++ b/lib/ui/components/brand_tab_bar/brand_tab_bar.dart @@ -64,7 +64,9 @@ class _BrandTabBarState extends State { var acitivColor = Theme.of(context).brightness == Brightness.dark ? BrandColors.white : BrandColors.black; - var color = currentIndex == index ? acitivColor : BrandColors.inactive; + + var isActive = currentIndex == index; + var color = isActive ? acitivColor : BrandColors.inactive; return InkWell( onTap: () => widget.controller.animateTo(index), child: Padding( @@ -75,7 +77,22 @@ class _BrandTabBarState extends State { children: [ Icon(iconData, color: color), SizedBox(height: 3), - Text(label, style: TextStyle(fontSize: 9, color: color)) + Row( + children: [ + if (isActive) ...[ + Container( + height: 5, + width: 5, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: BrandColors.red2, + ), + ), + SizedBox(width: 5), + ], + Text(label, style: TextStyle(fontSize: 9, color: color)), + ], + ) ], ), ), diff --git a/lib/ui/components/brand_text/brand_text.dart b/lib/ui/components/brand_text/brand_text.dart index fb7cae10d6..b216e61b7c 100644 --- a/lib/ui/components/brand_text/brand_text.dart +++ b/lib/ui/components/brand_text/brand_text.dart @@ -8,24 +8,27 @@ enum TextType { h4, // caption body1, // normal body2, // with opacity - small + medium, + small, + onboardingTitle } class BrandText extends StatelessWidget { - const BrandText( - this.text, { - Key key, - this.style, - @required this.type, - this.overflow, - this.softWrap, - }) : super(key: key); + const BrandText(this.text, + {Key key, + this.style, + @required this.type, + this.overflow, + this.softWrap, + this.textAlign}) + : super(key: key); final String text; final TextStyle style; final TextType type; final TextOverflow overflow; final bool softWrap; + final TextAlign textAlign; factory BrandText.h1( String text, { @@ -38,6 +41,13 @@ class BrandText extends StatelessWidget { type: TextType.h1, style: style, ); + + factory BrandText.onboardingTitle(String text, {TextStyle style}) => + BrandText( + text, + type: TextType.onboardingTitle, + style: style, + ); factory BrandText.h2(String text, {TextStyle style}) => BrandText( text, type: TextType.h2, @@ -63,6 +73,10 @@ class BrandText extends StatelessWidget { type: TextType.body2, style: style, ); + factory BrandText.medium(String text, + {TextStyle style, TextAlign textAlign}) => + BrandText(text, + type: TextType.medium, style: style, textAlign: textAlign); factory BrandText.small(String text, {TextStyle style}) => BrandText( text, type: TextType.small, @@ -105,6 +119,15 @@ class BrandText extends StatelessWidget { case TextType.small: style = isDark ? smallStyle.copyWith(color: Colors.white) : smallStyle; break; + case TextType.onboardingTitle: + style = isDark + ? onboardingTitle.copyWith(color: Colors.white) + : onboardingTitle; + break; + case TextType.medium: + style = + isDark ? mediumStyle.copyWith(color: Colors.white) : mediumStyle; + break; } if (this.style != null) { style = style.merge(this.style); @@ -114,6 +137,7 @@ class BrandText extends StatelessWidget { style: style, overflow: overflow, softWrap: softWrap, + textAlign: textAlign, ); } } diff --git a/lib/ui/components/icon_status_mask/icon_status_mask.dart b/lib/ui/components/icon_status_mask/icon_status_mask.dart index d81643cf7b..f02167da60 100644 --- a/lib/ui/components/icon_status_mask/icon_status_mask.dart +++ b/lib/ui/components/icon_status_mask/icon_status_mask.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_colors.dart'; import 'package:selfprivacy/logic/models/state_types.dart'; -class IconStatusMaks extends StatelessWidget { - IconStatusMaks({this.child, this.status}); +class IconStatusMask extends StatelessWidget { + IconStatusMask({this.child, this.status}); final Icon child; final StateType status; diff --git a/lib/ui/components/not_ready_card/not_ready_card.dart b/lib/ui/components/not_ready_card/not_ready_card.dart new file mode 100644 index 0000000000..94ab541c66 --- /dev/null +++ b/lib/ui/components/not_ready_card/not_ready_card.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:selfprivacy/config/brand_colors.dart'; + +class NotReadyCard extends StatelessWidget { + const NotReadyCard({Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 15, vertical: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), color: BrandColors.gray6), + child: Text( + 'Завершите настройку приложения используя "Мастер подключения" для продолжения работы', + style: TextStyle(color: BrandColors.white), + ), + ); + } +} diff --git a/lib/ui/components/progress_bar/progress_bar.dart b/lib/ui/components/progress_bar/progress_bar.dart index ed3fc7eaf4..00f196cc13 100644 --- a/lib/ui/components/progress_bar/progress_bar.dart +++ b/lib/ui/components/progress_bar/progress_bar.dart @@ -24,54 +24,37 @@ class _ProgressBarState extends State { @override Widget build(BuildContext context) { double progress = 1 / widget.steps.length * (widget.activeIndex + 0.3); + var isDark = context.watch().state.isDarkModeOn; + var style = isDark ? progressTextStyleDark : progressTextStyleLight; + + var allSteps = widget.steps.asMap().map( + (i, step) { + var value = _stepTitle(index: i, style: style, step: step); + return MapEntry(i, value); + }, + ).values; + + List odd = []; + List even = []; + + var i = 0; + for (var step in allSteps) { + if (i.isEven) { + even.add(step); + } else { + odd.add(step); + } + i++; + } + even.add(Spacer()); + odd.insert(0, Spacer()); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - BrandText.h4('Progress'), + BrandText.h2('Progress'), SizedBox(height: 10), - Row( - children: widget.steps - .asMap() - .map( - (i, step) { - var isActive = i == widget.activeIndex; - var checked = i < widget.activeIndex; - - var isDark = - context.watch().state.isDarkModeOn; - var style = - isDark ? progressTextStyleDark : progressTextStyleLight; - - style = isActive - ? style.copyWith(fontWeight: FontWeight.w700) - : style; - return MapEntry( - i, - Expanded( - child: RichText( - textAlign: TextAlign.center, - text: TextSpan( - style: progressTextStyleLight, - children: [ - checked - ? WidgetSpan( - child: Padding( - padding: const EdgeInsets.only( - bottom: 1, right: 2), - child: Icon(BrandIcons.check, size: 14), - )) - : TextSpan(text: '${i + 1}.', style: style), - TextSpan(text: step, style: style) - ], - ), - ), - )); - }, - ) - .values - .toList(), - ), + Row(children: even), SizedBox(height: 3), Container( alignment: Alignment.centerLeft, @@ -98,8 +81,42 @@ class _ProgressBarState extends State { ); }, ), - ) + ), + SizedBox(height: 3), + Row( + children: odd, + ), ], ); } + + Expanded _stepTitle({ + int index, + TextStyle style, + String step, + }) { + var isActive = index == widget.activeIndex; + var checked = index < widget.activeIndex; + + style = isActive ? style.copyWith(fontWeight: FontWeight.w700) : style; + return Expanded( + flex: 2, + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + style: progressTextStyleLight, + children: [ + checked + ? WidgetSpan( + child: Padding( + padding: const EdgeInsets.only(bottom: 1, right: 2), + child: Icon(BrandIcons.check, size: 14), + )) + : TextSpan(text: '${index + 1}.', style: style), + TextSpan(text: step, style: style) + ], + ), + ), + ); + } } diff --git a/lib/ui/pages/initializing/initializing.dart b/lib/ui/pages/initializing/initializing.dart index 4e8448ee85..e2e68758c3 100644 --- a/lib/ui/pages/initializing/initializing.dart +++ b/lib/ui/pages/initializing/initializing.dart @@ -3,10 +3,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:selfprivacy/config/brand_theme.dart'; import 'package:selfprivacy/config/text_themes.dart'; +import 'package:selfprivacy/logic/cubit/forms/initializing/cloudflare_form_cubit.dart'; +import 'package:selfprivacy/logic/cubit/forms/initializing/domain_form_cubit.dart'; import 'package:selfprivacy/logic/cubit/forms/initializing/hetzner_form_cubit.dart'; -import 'package:selfprivacy/logic/cubit/initializing/initializing_cubit.dart'; +import 'package:selfprivacy/logic/cubit/forms/initializing/user_form_cubit.dart'; +import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart'; -import 'package:selfprivacy/logic/models/user.dart'; import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; import 'package:selfprivacy/ui/components/brand_card/brand_card.dart'; import 'package:selfprivacy/ui/components/brand_modal_sheet/brand_modal_sheet.dart'; @@ -16,96 +18,71 @@ import 'package:selfprivacy/ui/components/progress_bar/progress_bar.dart'; import 'package:selfprivacy/ui/pages/rootRoute.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart'; -class InitializingPage extends StatefulWidget { - const InitializingPage({Key key}) : super(key: key); - - @override - _InitializingPageState createState() => _InitializingPageState(); -} - -class _InitializingPageState extends State { - PageController pageController = PageController(viewportFraction: 1); - - @override - void dispose() { - pageController.dispose(); - super.dispose(); - } - +class InitializingPage extends StatelessWidget { @override Widget build(BuildContext context) { - var cubit = context.watch(); - - return SafeArea( - child: Scaffold( - body: ListView( - children: [ - Padding( - padding: brandPagePadding1, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BrandText.h4('Начало'), - BrandText.h1('SelfPrivacy'), - SizedBox( - height: 10, - ), - RichText( - text: TextSpan( - children: [ - TextSpan( - text: - 'Для устойчивости и приватности требует много учёток. Полная инструкция на ', - style: body2Style, - ), - BrandSpanButton.link( - text: - 'https://selfprivacy.org/posts/getting_started/', - urlString: - 'https://selfprivacy.org/posts/getting_started/', - ), + var cubit = context.watch(); + var actualPage = [ + _stepHetzner(cubit), + _stepCloudflare(cubit), + _stepDomain(cubit), + _stepUser(cubit), + _stepServer(cubit), + Container(child: Text('Everythigng is initialized')) + ][cubit.state.progress]; + return BlocListener( + listener: (context, state) { + if (state.isFullyInitilized) { + Navigator.of(context).pushReplacement(materialRoute(RootPage())); + } + }, + child: SafeArea( + child: Scaffold( + body: ListView( + children: [ + Padding( + padding: brandPagePadding1, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ProgressBar( + steps: [ + 'Hetzner', + 'CloudFlare', + 'Domain', + 'User', + 'Server', + 'Check' ], + activeIndex: cubit.state.progress, ), - ), - SizedBox(height: 10), - ProgressBar( - steps: ['Server', 'DNS', 'Domain', 'User'], - // progress: cubit.state.progress, - activeIndex: cubit.state.progress, - ), - SizedBox(height: 20), - ], + ], + ), ), - ), - Container( - height: 500, - child: PageView( - // physics: NeverScrollableScrollPhysics(), - controller: pageController, - children: [ - _addCard(_stepOne(cubit)), - _addCard(_stepTwo(cubit)), - _addCard(_stepThree(cubit)), - _addCard(_stepFour(cubit)), - ], + _addCard( + AnimatedSwitcher( + duration: Duration(milliseconds: 300), + child: actualPage, + ), ), - ), - BrandButton.text(title: 'Настрою потом', onPressed: _goToMainPage), - SizedBox(height: 30), - ], + BrandButton.text( + title: + cubit.state.isFullyInitilized ? 'Close' : 'Настрою потом', + onPressed: () { + Navigator.of(context).pushAndRemoveUntil( + materialRoute(RootPage()), + (predicate) => predicate == null, + ); + }), + SizedBox(height: 30), + ], + ), ), ), ); } - void _goToMainPage() { - Navigator.of(context).pushAndRemoveUntil( - materialRoute(RootPage()), - (predicate) => predicate == null, - ); - } - - Widget _stepOne(InitializingCubit initializingCubit) { + Widget _stepHetzner(AppConfigCubit initializingCubit) { return BlocProvider( create: (context) => HetznerFormCubit(initializingCubit), child: Builder(builder: (context) { @@ -124,19 +101,17 @@ class _InitializingPageState extends State { CubitFormTextField( formFieldCubit: formCubit.apiKey, textAlign: TextAlign.center, - keyboardType: TextInputType.number, scrollPadding: EdgeInsets.only(bottom: 70), decoration: InputDecoration( hintText: 'Hetzner API Token', ), ), - SizedBox(height: 20), + Spacer(), BrandButton.rised( onPressed: formCubit.state.isSubmitting ? null : formCubit.trySubmit, title: 'Подключить', ), - Spacer(), SizedBox(height: 10), BrandButton.text( onPressed: () => _showModal(context, _HowHetzner()), @@ -159,110 +134,161 @@ class _InitializingPageState extends State { ); } - Widget _stepTwo(InitializingCubit cubit) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset('assets/images/logos/cloudflare.png'), - BrandText.h2('Подключите CloudFlare DNS'), - SizedBox(height: 10), - BrandText.body2('Для управления DNS вашего домена'), - Expanded( - child: _MockForm( - hintText: 'CloudFlare API Token', - length: 64, - onPressed: () { - cubit.setCloudFlare('key'); - pageController.animateToPage( - 2, - curve: Curves.easeIn, - duration: Duration(milliseconds: 200), - ); - }, - ), - ), - SizedBox(height: 20), - BrandButton.text( - onPressed: () {}, - title: 'Как получить API Token', - ), - ], + Widget _stepCloudflare(AppConfigCubit initializingCubit) { + return BlocProvider( + create: (context) => CloudFlareFormCubit(initializingCubit), + child: Builder(builder: (context) { + var formCubit = context.watch(); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Spacer(), + Image.asset('assets/images/logos/cloudflare.png'), + BrandText.h2('Подключите CloudFlare'), + SizedBox(height: 10), + BrandText.body2('Для управления DNS вашего домена'), + Spacer(), + CubitFormTextField( + formFieldCubit: formCubit.apiKey, + textAlign: TextAlign.center, + scrollPadding: EdgeInsets.only(bottom: 70), + decoration: InputDecoration( + hintText: 'CloudFlare API Token', + ), + ), + Spacer(), + BrandButton.rised( + onPressed: + formCubit.state.isSubmitting ? null : formCubit.trySubmit, + title: 'Подключить', + ), + SizedBox(height: 10), + BrandButton.text( + onPressed: () {}, + title: 'Как получить API Token', + ), + ], + ); + }), ); } - Widget _stepThree(InitializingCubit cubit) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 10), - BrandText.h2('Введите домен:'), - Expanded( - child: _MockForm( - hintText: 'домен', - length: 10, - onPressed: () { - cubit.setDomain('domain'); - pageController.animateToPage( - 3, - curve: Curves.easeIn, - duration: Duration(milliseconds: 200), - ); - }, - ), - ), - SizedBox(height: 10), - BrandButton.text( - onPressed: () => _showModal(context, _HowHetzner()), - title: 'Как получить API Token', - ), - ], + Widget _stepDomain(AppConfigCubit initializingCubit) { + return BlocProvider( + create: (context) => DomainFormCubit(initializingCubit), + child: Builder(builder: (context) { + var formCubit = context.watch(); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Spacer(), + BrandText.h2('Введите домен:'), + SizedBox(height: 10), + CubitFormTextField( + keyboardType: TextInputType.emailAddress, + formFieldCubit: formCubit.domainName, + textAlign: TextAlign.center, + scrollPadding: EdgeInsets.only(bottom: 70), + decoration: InputDecoration( + hintText: 'Домен', + ), + ), + Spacer(), + BrandButton.rised( + onPressed: + formCubit.state.isSubmitting ? null : formCubit.trySubmit, + title: 'Подключить', + ), + SizedBox(height: 10), + BrandButton.text( + onPressed: () => _showModal(context, _HowHetzner()), + title: 'Как получить API Token', + ), + ], + ); + }), ); } - Widget _stepFour(InitializingCubit cubit) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 10), - Expanded( - child: Column( - children: [ - TextField( - decoration: InputDecoration( - hintText: 'нинейм', - ), + Widget _stepUser(AppConfigCubit initializingCubit) { + return BlocProvider( + create: (context) => UserFormCubit(initializingCubit), + child: Builder(builder: (context) { + var formCubit = context.watch(); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Spacer(), + SizedBox(height: 10), + CubitFormTextField( + formFieldCubit: formCubit.userName, + textAlign: TextAlign.center, + scrollPadding: EdgeInsets.only(bottom: 70), + decoration: InputDecoration( + hintText: 'Никнейм', ), - SizedBox(height: 10), - TextField( - obscureText: true, - decoration: InputDecoration( - hintText: 'пароль', - ), + ), + SizedBox(height: 10), + CubitFormTextField( + formFieldCubit: formCubit.password, + textAlign: TextAlign.center, + scrollPadding: EdgeInsets.only(bottom: 70), + decoration: InputDecoration( + hintText: 'Пароль', ), - Spacer(), - BrandButton.rised( - onPressed: () { - cubit.setRootUser( - User(login: 'aa', password: 'bbb'), - ); - _goToMainPage(); - }, - title: 'some text', - ), - ], - ), - ), - SizedBox(height: 10), - BrandButton.text( - onPressed: () => _showModal(context, _HowHetzner()), - title: 'Как получить API Token', - ), - ], + ), + Spacer(), + BrandButton.rised( + onPressed: + formCubit.state.isSubmitting ? null : formCubit.trySubmit, + title: 'Подключить', + ), + SizedBox(height: 10), + BrandButton.text( + onPressed: () => _showModal(context, _HowHetzner()), + title: 'Как получить API Token', + ), + ], + ); + }), ); } + Widget _stepServer(AppConfigCubit appConfigCubit) { + var isLoading = appConfigCubit.state.isLoading; + return Builder(builder: (context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Spacer( + flex: 2, + ), + BrandText.h2('Создать сервер'), + SizedBox(height: 10), + BrandText.body2('Создать сервер'), + Spacer(), + BrandButton.rised( + onPressed: isLoading ? null : appConfigCubit.createServer, + title: isLoading ? 'loading' : 'Создать сервер', + ), + Spacer( + flex: 2, + ), + BrandButton.text( + onPressed: () => _showModal(context, _HowHetzner()), + title: 'Что это значит?', + ), + ], + ); + }); + } + Widget _addCard(Widget child) { - return Padding( + return Container( + height: 500, padding: brandPagePadding2, child: BrandCard( child: child, @@ -322,235 +348,3 @@ class _HowHetzner extends StatelessWidget { ); } } - -// class _MockSuccess extends StatelessWidget { -// const _MockSuccess({Key key, this.type}) : super(key: key); - -// final ProviderType type; - -// @override -// Widget build(BuildContext context) { -// String text; - -// switch (type) { -// case ProviderType.server: -// text = '1. Cервер подключен'; -// break; -// case ProviderType.domain: -// text = '2. Домен настроен'; -// break; -// case ProviderType.backup: -// text = '3. Резервное копирование настроенно'; -// break; -// } -// return BrandCard( -// child: Row( -// mainAxisAlignment: MainAxisAlignment.spaceBetween, -// children: [ -// BrandText.h3(text), -// Icon( -// Icons.check, -// color: BrandColors.green1, -// ), -// ], -// ), -// ); -// } -// } - -class _MockForm extends StatefulWidget { - const _MockForm({ - Key key, - @required this.hintText, - this.submitButtonText = 'Подключить', - @required this.onPressed, - @required this.length, - }) : super(key: key); - - final String hintText; - final String submitButtonText; - final int length; - - final VoidCallback onPressed; - - @override - __MockFormState createState() => __MockFormState(); -} - -class __MockFormState extends State<_MockForm> { - String text = ''; - bool _valid = true; - bool _touched = false; - - onPressed() { - if (text.length == widget.length) { - setState(() { - _touched = true; - _valid = true; - widget.onPressed(); - }); - } else { - setState(() { - _touched = true; - _valid = false; - }); - } - } - - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox(height: 20), - TextField( - onChanged: (value) { - if (_touched) { - if (value.length == widget.length) { - setState(() { - _valid = true; - text = value; - }); - } else { - setState(() { - _valid = false; - text = value; - }); - } - } else { - setState(() { - text = value; - }); - } - }, - decoration: InputDecoration( - hintText: widget.hintText, - errorText: - _valid ? null : 'Длинна должна быть ${widget.length} символа', - ), - ), - Spacer(), - BrandButton.rised( - onPressed: _valid ? onPressed : null, - title: widget.submitButtonText, - ), - ], - ); - } -} - -// Widget getCard(BuildContext context, ProviderModel model) { -// var cubit = context.watch(); -// if (model.state == StateType.stable) { -// return _MockSuccess(type: model.type); -// } -// switch (model.type) { -// case ProviderType.server: -// return BrandCard( -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// Image.asset('assets/images/logos/hetzner.png'), -// SizedBox(height: 10), -// BrandText.h2('1. Подключите сервер Hetzner'), -// SizedBox(height: 10), -// BrandText.body2( -// 'Здесь будут жить наши данные и SelfPrivacy-сервисы'), -// _MockForm( -// hintText: 'Hetzner API Token', -// length: 48, -// onPressed: () { -// var provider = cubit.state.all -// .firstWhere((p) => p.type == ProviderType.server); -// cubit.connect(provider); -// }, -// ), -// SizedBox(height: 20), -// BrandButton.text( -// onPressed: () => _showModal(context, _HowHetzner()), -// title: 'Как получить API Token', -// ), -// ], -// ), -// ); -// break; -// case ProviderType.domain: -// return BrandCard( -// isBlocked: true, -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// Image.asset('assets/images/logos/namecheap.png'), -// SizedBox(height: 10), -// BrandText.h2('2. Настройте домен'), -// SizedBox(height: 10), -// RichText( -// text: TextSpan( -// children: [ -// TextSpan( -// text: 'Зарегистрируйте домен в ', -// style: body2Style, -// ), -// BrandSpanButton.link( -// text: 'NameCheap', -// urlString: 'https://www.namecheap.com', -// ), -// TextSpan( -// text: -// ' или у любого другого регистратора. После этого настройте его на DNS-сервер CloudFlare', -// style: body2Style, -// ), -// ], -// ), -// ), -// _MockForm( -// hintText: 'Домен, например, selfprivacy.org', -// submitButtonText: 'Проверить DNS', -// length: 2, -// onPressed: () {}, -// ), -// SizedBox(height: 20), -// BrandButton.text( -// onPressed: () {}, -// title: 'Как настроить DNS CloudFlare', -// ), -// SizedBox(height: 10), -// Image.asset('assets/images/logos/cloudflare.png'), -// SizedBox(height: 10), -// ], -// ), -// ); -// break; -// case ProviderType.backup: -// return BrandCard( -// isBlocked: true, -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// Image.asset('assets/images/logos/aws.png'), -// SizedBox(height: 10), -// BrandText.h2('4. Подключите Amazon AWS для бекапа'), -// SizedBox(height: 10), -// BrandText.body2( -// 'IaaS-провайдер, для бесплатного хранения резервных копии ваших данных в зашифрованном виде'), -// _MockForm( -// hintText: 'Amazon AWS Access Key', -// length: 2, -// onPressed: () { -// var provider = cubit.state.all -// .firstWhere((p) => p.type == ProviderType.backup); -// cubit.connect(provider); -// }, -// ), -// SizedBox(height: 20), -// BrandButton.text( -// onPressed: () {}, -// title: 'Как получить API Token', -// ), -// ], -// ), -// ); -// } - -// return null; -// } diff --git a/lib/ui/pages/more/app_settings/app_setting.dart b/lib/ui/pages/more/app_settings/app_setting.dart index 7988ee008a..2e6113f547 100644 --- a/lib/ui/pages/more/app_settings/app_setting.dart +++ b/lib/ui/pages/more/app_settings/app_setting.dart @@ -2,9 +2,11 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_colors.dart'; import 'package:selfprivacy/config/brand_theme.dart'; import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart'; +import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart'; import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; +import 'package:selfprivacy/utils/named_font_weight.dart'; class AppSettingsPage extends StatefulWidget { const AppSettingsPage({Key key}) : super(key: key); @@ -53,11 +55,75 @@ class _AppSettingsPageState extends State { activeColor: BrandColors.green1, activeTrackColor: BrandColors.green2, value: Theme.of(context).brightness == Brightness.dark, - onChanged: (value) => - appSettings.update(isDarkModeOn: !isDarkModeOn), + onChanged: (value) => appSettings.updateDarkMode( + isDarkModeOn: !isDarkModeOn), ), ], ), + ), + Container( + padding: EdgeInsets.only(top: 20, bottom: 5), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(width: 1, color: BrandColors.dividerColor), + )), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: _TextColumn( + title: 'Reset app config', + value: 'Reset api keys and root user', + ), + ), + SizedBox(width: 5), + RaisedButton( + color: BrandColors.red1, + child: Text( + 'Reset', + style: TextStyle( + color: BrandColors.white, + fontWeight: NamedFontWeight.demiBold, + ), + ), + onPressed: () { + showDialog( + context: context, + child: AlertDialog( + title: Text('Are you sure?'), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text('Reset all keys?'), + ], + ), + ), + actions: [ + TextButton( + child: Text( + 'Reset', + style: TextStyle( + color: BrandColors.red1, + ), + ), + onPressed: () { + context.read().reset(); + Navigator.of(context)..pop()..pop(); + }, + ), + TextButton( + child: Text('Cancel'), + onPressed: () { + Navigator.of(context)..pop(); + }, + ), + ], + )); + }, + ) + ], + ), ) ], ), @@ -88,10 +154,6 @@ class _TextColumn extends StatelessWidget { style: TextStyle(color: hasWarning ? BrandColors.warning : null), ), SizedBox(height: 5), - BrandText.body1( - title, - style: TextStyle(color: hasWarning ? BrandColors.warning : null), - ), BrandText.body1(value, style: TextStyle( fontSize: 13, diff --git a/lib/ui/pages/more/more.dart b/lib/ui/pages/more/more.dart index 6a712b5472..253a41ea87 100644 --- a/lib/ui/pages/more/more.dart +++ b/lib/ui/pages/more/more.dart @@ -6,6 +6,8 @@ import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/ui/pages/initializing/initializing.dart'; +import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart'; +import 'package:selfprivacy/ui/pages/rootRoute.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart'; import 'about/about.dart'; @@ -49,6 +51,11 @@ class MorePage extends StatelessWidget { iconData: BrandIcons.help, goTo: InfoPage(), ), + _NavItem( + title: 'Onboarding', + iconData: BrandIcons.triangle, + goTo: OnboardingPage(nextPage: RootPage()), + ), ], ), ) diff --git a/lib/ui/pages/onboarding/onboarding.dart b/lib/ui/pages/onboarding/onboarding.dart index 2b10a3359b..e720581457 100644 --- a/lib/ui/pages/onboarding/onboarding.dart +++ b/lib/ui/pages/onboarding/onboarding.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; +import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart'; import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; -import 'package:selfprivacy/ui/pages/initializing/initializing.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart'; class OnboardingPage extends StatefulWidget { - const OnboardingPage({Key key}) : super(key: key); + const OnboardingPage({Key key, @required this.nextPage}) : super(key: key); + final Widget nextPage; @override _OnboardingPageState createState() => _OnboardingPageState(); } @@ -107,8 +108,9 @@ class _OnboardingPageState extends State { ), BrandButton.rised( onPressed: () { + context.read().turnOffOnboarding(); Navigator.of(context) - .pushReplacement(materialRoute(InitializingPage())); + .pushReplacement(materialRoute(widget.nextPage)); }, title: 'Понял', ), diff --git a/lib/ui/pages/providers/providers.dart b/lib/ui/pages/providers/providers.dart index dc9552a377..40743943be 100644 --- a/lib/ui/pages/providers/providers.dart +++ b/lib/ui/pages/providers/providers.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_theme.dart'; -import 'package:selfprivacy/logic/cubit/initializing/initializing_cubit.dart'; +import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart'; import 'package:selfprivacy/logic/models/provider.dart'; import 'package:selfprivacy/logic/models/state_types.dart'; @@ -9,6 +9,7 @@ import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; import 'package:selfprivacy/ui/components/brand_modal_sheet/brand_modal_sheet.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/ui/components/icon_status_mask/icon_status_mask.dart'; +import 'package:selfprivacy/ui/components/not_ready_card/not_ready_card.dart'; import 'package:selfprivacy/ui/pages/providers/settings/settings.dart'; import 'package:selfprivacy/utils/route_transitions/basic.dart'; @@ -22,9 +23,12 @@ class ProvidersPage extends StatefulWidget { class _ProvidersPageState extends State { @override Widget build(BuildContext context) { + var isReady = context.watch().state.isFullyInitilized; + final cards = ProviderType.values - .map((type) => - _Card(provider: ProviderModel(state: StateType.stable, type: type))) + .map((type) => _Card( + provider: + ProviderModel(state: StateType.uninitialized, type: type))) .toList(); return Scaffold( appBar: PreferredSize( @@ -33,7 +37,13 @@ class _ProvidersPageState extends State { ), body: ListView( padding: brandPagePadding2, - children: cards, + children: [ + if (!isReady) ...[ + NotReadyCard(), + SizedBox(height: 24), + ], + ...cards, + ], ), ); } @@ -48,8 +58,6 @@ class _Card extends StatelessWidget { String title; String message; String stableText; - var isFullyInitilized = - context.watch().state.isFullyInitilized; switch (provider.type) { case ProviderType.server: @@ -80,11 +88,10 @@ class _Card extends StatelessWidget { }, ), child: BrandCard( - isBlocked: !isFullyInitilized, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - IconStatusMaks( + IconStatusMask( status: provider.state, child: Icon(provider.icon, size: 30, color: Colors.white), ), @@ -176,7 +183,7 @@ class _ProviderDetails extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 13), - IconStatusMaks( + IconStatusMask( status: provider.state, child: Icon(provider.icon, size: 40, color: Colors.white), diff --git a/lib/ui/pages/rootRoute.dart b/lib/ui/pages/rootRoute.dart index 949180b46d..8182a5c807 100644 --- a/lib/ui/pages/rootRoute.dart +++ b/lib/ui/pages/rootRoute.dart @@ -1,9 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:selfprivacy/logic/cubit/initializing/initializing_cubit.dart'; -import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart'; import 'package:selfprivacy/ui/components/brand_tab_bar/brand_tab_bar.dart'; -import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/ui/pages/more/more.dart'; import 'package:selfprivacy/ui/pages/providers/providers.dart'; import 'package:selfprivacy/ui/pages/services/services.dart'; @@ -34,9 +31,6 @@ class _RootPageState extends State @override Widget build(BuildContext context) { - var isUserFilled = - context.watch().state.isFullyInitilized; - return SafeArea( child: Scaffold( body: TabBarView( @@ -44,7 +38,7 @@ class _RootPageState extends State children: [ ProvidersPage(), ServicesPage(), - isUserFilled ? UsersPage() : _NotReady(), + UsersPage(), MorePage(), ], ), @@ -55,20 +49,3 @@ class _RootPageState extends State ); } } - -class _NotReady extends StatelessWidget { - const _NotReady({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - BrandText.h3('Not ready'), - BrandText.body2('Finish providers initialization first'), - ], - ), - ); - } -} diff --git a/lib/ui/pages/services/services.dart b/lib/ui/pages/services/services.dart index 8fde410678..f92c07e48c 100644 --- a/lib/ui/pages/services/services.dart +++ b/lib/ui/pages/services/services.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_theme.dart'; -import 'package:selfprivacy/logic/cubit/initializing/initializing_cubit.dart'; +import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/services/services_cubit.dart'; import 'package:selfprivacy/logic/models/service.dart'; import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; @@ -9,6 +9,7 @@ import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; import 'package:selfprivacy/ui/components/icon_status_mask/icon_status_mask.dart'; +import 'package:selfprivacy/ui/components/not_ready_card/not_ready_card.dart'; class ServicesPage extends StatefulWidget { ServicesPage({Key key}) : super(key: key); @@ -23,6 +24,8 @@ class _ServicesPageState extends State { final serviceCubit = context.watch(); final connected = serviceCubit.state.connected; final uninitialized = serviceCubit.state.uninitialized; + var isReady = context.watch().state.isFullyInitilized; + return Scaffold( appBar: PreferredSize( child: BrandHeader(title: 'Сервисы'), @@ -31,6 +34,7 @@ class _ServicesPageState extends State { body: ListView( padding: brandPagePadding2, children: [ + if (!isReady) NotReadyCard(), SizedBox(height: 24), ...connected.map((service) => _Card(service: service)).toList(), if (uninitialized.isNotEmpty) ...[ @@ -53,7 +57,6 @@ class _Card extends StatelessWidget { String title; IconData iconData; String description; - var isFullyInitilized = context.watch().state.isFullyInitilized; switch (service.type) { case ServiceTypes.messanger: @@ -85,11 +88,10 @@ class _Card extends StatelessWidget { break; } return BrandCard( - isBlocked: !isFullyInitilized, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - IconStatusMaks( + IconStatusMask( status: service.state, child: Icon(iconData, size: 30, color: Colors.white), ), diff --git a/lib/ui/pages/users/empty.dart b/lib/ui/pages/users/empty.dart new file mode 100644 index 0000000000..8f89cc6ae8 --- /dev/null +++ b/lib/ui/pages/users/empty.dart @@ -0,0 +1,37 @@ +part of 'users.dart'; + +class _NoUsers extends StatelessWidget { + const _NoUsers({Key key, @required this.text}) + : assert(text != null), + super(key: key); + + final String text; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(BrandIcons.users, size: 50, color: BrandColors.grey7), + SizedBox(height: 20), + BrandText.h2( + 'Здесь пока никого', + style: TextStyle( + color: BrandColors.grey7, + ), + ), + SizedBox(height: 10), + BrandText.medium( + text, + textAlign: TextAlign.center, + style: TextStyle( + color: BrandColors.grey7, + ), + ), + ], + ), + ); + } +} diff --git a/lib/ui/pages/users/fab.dart b/lib/ui/pages/users/fab.dart new file mode 100644 index 0000000000..7aa7222758 --- /dev/null +++ b/lib/ui/pages/users/fab.dart @@ -0,0 +1,34 @@ +part of 'users.dart'; + +class _Fab extends StatelessWidget { + const _Fab({Key key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + width: 48.0, + height: 48.0, + child: RawMaterialButton( + fillColor: BrandColors.blue, + shape: CircleBorder(), + elevation: 0.0, + highlightElevation: 2, + child: Icon( + Icons.add, + color: Colors.white, + size: 34, + ), + onPressed: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (BuildContext context) { + return _NewUser(); + }, + ); + }, + ), + ); + } +} diff --git a/lib/ui/pages/users/new_user.dart b/lib/ui/pages/users/new_user.dart new file mode 100644 index 0000000000..d76715c5e3 --- /dev/null +++ b/lib/ui/pages/users/new_user.dart @@ -0,0 +1,74 @@ +part of 'users.dart'; + +class _NewUser extends StatefulWidget { + const _NewUser({Key key}) : super(key: key); + + @override + __NewUserState createState() => __NewUserState(); +} + +class __NewUserState extends State<_NewUser> { + var passController = TextEditingController(text: genPass()); + + @override + Widget build(BuildContext context) { + // final usersCubit = context.watch(); + + return BrandModalSheet( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BrandHeader(title: 'Новый пользователь'), + SizedBox(width: 14), + Padding( + padding: brandPagePadding2, + child: Column( + children: [ + TextField( + decoration: InputDecoration( + labelText: 'Логин', + suffixText: '@example', + ), + ), + SizedBox(height: 20), + TextField( + controller: passController, + decoration: InputDecoration( + alignLabelWithHint: false, + labelText: 'Пароль', + suffixIcon: Padding( + padding: const EdgeInsets.only(right: 8), + child: IconButton( + icon: Icon( + BrandIcons.refresh, + color: BrandColors.blue, + ), + onPressed: () { + passController.value = + TextEditingValue(text: genPass()); + }, + ), + ), + ), + ), + SizedBox(height: 30), + BrandButton.rised( + onPressed: () { + Navigator.pop(context); + }, + title: 'Создать', + ), + SizedBox(height: 40), + Text( + 'Новый пользователь автоматически получит доступ ко всем сервисам. Ещё какое-то описание.'), + SizedBox(height: 30), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/ui/pages/users/user.dart b/lib/ui/pages/users/user.dart new file mode 100644 index 0000000000..8084969d28 --- /dev/null +++ b/lib/ui/pages/users/user.dart @@ -0,0 +1,40 @@ +part of 'users.dart'; + +class _User extends StatelessWidget { + const _User({Key key, this.user}) : super(key: key); + + final User user; + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (BuildContext context) { + return _UserDetails(user: user); + }, + ); + }, + child: Container( + padding: brandPagePadding2, + height: 48, + child: Row( + children: [ + Container( + width: 17, + height: 17, + decoration: BoxDecoration( + color: user.color, + shape: BoxShape.circle, + ), + ), + SizedBox(width: 20), + BrandText.h4(user.login), + ], + ), + ), + ); + } +} diff --git a/lib/ui/pages/users/user_details.dart b/lib/ui/pages/users/user_details.dart new file mode 100644 index 0000000000..6311fc4d45 --- /dev/null +++ b/lib/ui/pages/users/user_details.dart @@ -0,0 +1,159 @@ +part of 'users.dart'; + +class _UserDetails extends StatelessWidget { + const _UserDetails({ + Key key, + this.user, + }) : super(key: key); + + final User user; + + @override + Widget build(BuildContext context) { + return BrandModalSheet( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 200, + decoration: BoxDecoration( + color: user.color, + borderRadius: BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Align( + alignment: Alignment.centerRight, + child: Padding( + padding: EdgeInsets.symmetric( + vertical: 4, + horizontal: 2, + ), + child: PopupMenuButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0), + ), + onSelected: (PopupMenuItemType result) { + switch (result) { + case PopupMenuItemType.reset: + break; + case PopupMenuItemType.delete: + showDialog( + context: context, + child: AlertDialog( + title: Text('Подтверждение '), + content: SingleChildScrollView( + child: ListBody( + children: [ + Text('удалить учетную запись?'), + ], + ), + ), + actions: [ + TextButton( + child: Text('Отменить'), + onPressed: () { + Navigator.of(context)..pop(); + }, + ), + TextButton( + child: Text( + 'Удалить', + style: TextStyle( + color: BrandColors.red1, + ), + ), + onPressed: () { + Navigator.of(context)..pop()..pop(); + }, + ), + ], + )); + break; + } + }, + icon: Icon(Icons.more_vert), + itemBuilder: (BuildContext context) => [ + PopupMenuItem( + value: PopupMenuItemType.reset, + child: Container( + padding: EdgeInsets.only(left: 5), + child: Text('Сбросить пароль'), + ), + ), + PopupMenuItem( + value: PopupMenuItemType.delete, + child: Container( + padding: EdgeInsets.only(left: 5), + child: Text( + 'Удалить', + style: TextStyle(color: BrandColors.red1), + ), + ), + ), + ], + ), + ), + ), + Spacer(), + Padding( + padding: EdgeInsets.symmetric( + vertical: 20, + horizontal: 15, + ), + child: BrandText.h1( + user.login, + softWrap: true, + overflow: TextOverflow.ellipsis, + )), + ], + ), + ), + SizedBox(height: 20), + Padding( + padding: brandPagePadding2.copyWith(bottom: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BrandText.small('Учетная запись'), + Container( + height: 40, + alignment: Alignment.centerLeft, + child: BrandText.h4('${user.login}@example.com'), + ), + SizedBox(height: 14), + BrandText.small('Пароль'), + Container( + height: 40, + alignment: Alignment.centerLeft, + child: BrandText.h4(user.password), + ), + SizedBox(height: 24), + BrandDivider(), + SizedBox(height: 20), + BrandButton.iconText( + title: 'Отправить реквизиты для входа', + icon: Icon(BrandIcons.share), + onPressed: () {}, + ), + SizedBox(height: 20), + BrandDivider(), + SizedBox(height: 20), + Text( + 'Вам был создан доступ к сервисам с логином и паролем к сервисам:- E-mail с адресом - Менеджер паролей: - Файловое облако: - Видеоконференция - Git сервер '), + ], + ), + ) + ], + ), + ); + } +} + +enum PopupMenuItemType { + reset, + delete, +} diff --git a/lib/ui/pages/users/users.dart b/lib/ui/pages/users/users.dart index 5bfebb1cca..809e6a70f3 100644 --- a/lib/ui/pages/users/users.dart +++ b/lib/ui/pages/users/users.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:selfprivacy/config/brand_colors.dart'; import 'package:selfprivacy/config/brand_theme.dart'; +import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart'; import 'package:selfprivacy/logic/cubit/users/users_cubit.dart'; import 'package:selfprivacy/logic/models/user.dart'; import 'package:selfprivacy/ui/components/brand_button/brand_button.dart'; @@ -9,318 +10,74 @@ import 'package:selfprivacy/ui/components/brand_header/brand_header.dart'; import 'package:selfprivacy/ui/components/brand_icons/brand_icons.dart'; import 'package:selfprivacy/ui/components/brand_modal_sheet/brand_modal_sheet.dart'; import 'package:selfprivacy/ui/components/brand_text/brand_text.dart'; +import 'package:selfprivacy/ui/components/not_ready_card/not_ready_card.dart'; import 'package:selfprivacy/utils/password_generator.dart'; +part 'fab.dart'; +part 'new_user.dart'; +part 'user_details.dart'; +part 'user.dart'; +part 'empty.dart'; + class UsersPage extends StatelessWidget { const UsersPage({Key key}) : super(key: key); @override Widget build(BuildContext context) { final usersCubit = context.watch(); + var isReady = context.watch().state.isFullyInitilized; final users = usersCubit.state.users; + final isEmpty = usersCubit.state.isEmpty; + + Widget child; + + if (!isReady) { + child = isNotReady(); + } else { + child = isEmpty + ? Container( + alignment: Alignment.center, + child: _NoUsers( + text: 'Добавьте первого пользователя', + ), + ) + : ListView( + children: [ + ...users.map((user) => _User(user: user)), + ], + ); + } + return Scaffold( appBar: PreferredSize( child: BrandHeader(title: 'Пользователи'), preferredSize: Size.fromHeight(52), ), - floatingActionButton: Container( - width: 48.0, - height: 48.0, - child: RawMaterialButton( - fillColor: BrandColors.blue, - shape: CircleBorder(), - elevation: 0.0, - highlightElevation: 2, - child: Icon( - Icons.add, - color: Colors.white, - size: 34, - ), - onPressed: () { - showModalBottomSheet( - context: context, - isScrollControlled: true, - backgroundColor: Colors.transparent, - builder: (BuildContext context) { - return _NewUser(); - }, - ); - }, - ), - ), - body: ListView( - children: [ - ...users.map((user) => _User(user: user)), - ], - ), + floatingActionButton: isReady ? _Fab() : null, + body: child, ); } -} -class _User extends StatelessWidget { - const _User({Key key, this.user}) : super(key: key); - - final User user; - @override - Widget build(BuildContext context) { - return InkWell( - onTap: () { - showModalBottomSheet( - context: context, - isScrollControlled: true, - backgroundColor: Colors.transparent, - builder: (BuildContext context) { - return _UserDetails(user: user); - }, - ); - }, - child: Container( - padding: brandPagePadding2, - height: 48, - child: Row( - children: [ - Container( - width: 17, - height: 17, - decoration: BoxDecoration( - color: user.color, - shape: BoxShape.circle, - ), - ), - SizedBox(width: 20), - BrandText.h4(user.login), - ], + Widget isNotReady() { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: NotReadyCard(), ), - ), - ); - } -} - -class _NewUser extends StatefulWidget { - const _NewUser({Key key}) : super(key: key); - - @override - __NewUserState createState() => __NewUserState(); -} - -class __NewUserState extends State<_NewUser> { - var passController = TextEditingController(text: genPass()); - - @override - Widget build(BuildContext context) { - return BrandModalSheet( - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BrandHeader(title: 'Новый пользователь'), - SizedBox(width: 14), - Padding( - padding: brandPagePadding2, - child: Column( - children: [ - TextField( - decoration: InputDecoration( - labelText: 'Логин', - suffixText: '@example', - ), - ), - SizedBox(height: 20), - TextField( - controller: passController, - decoration: InputDecoration( - alignLabelWithHint: false, - labelText: 'Пароль', - suffixIcon: Padding( - padding: const EdgeInsets.only(right: 8), - child: IconButton( - icon: Icon( - BrandIcons.refresh, - color: BrandColors.blue, - ), - onPressed: () { - passController.value = - TextEditingValue(text: genPass()); - }, - ), - ), - ), - ), - SizedBox(height: 30), - BrandButton.rised( - onPressed: () { - Navigator.pop(context); - }, - title: 'Создать', - ), - SizedBox(height: 40), - Text( - 'Новый пользователь автоматически получит доступ ко всем сервисам. Ещё какое-то описание.'), - SizedBox(height: 30), - ], + Expanded( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Center( + child: _NoUsers( + text: + 'Подключите сервер, домен и DNS в разеде Провайдеры, чтобы добавить первого пользователя', ), ), - ], - ), - ), - ); - } -} - -class _UserDetails extends StatelessWidget { - const _UserDetails({ - Key key, - this.user, - }) : super(key: key); - - final User user; - - @override - Widget build(BuildContext context) { - return BrandModalSheet( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: 200, - decoration: BoxDecoration( - color: user.color, - borderRadius: BorderRadius.vertical( - top: Radius.circular(20), - ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Align( - alignment: Alignment.centerRight, - child: Padding( - padding: EdgeInsets.symmetric( - vertical: 4, - horizontal: 2, - ), - child: PopupMenuButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10.0), - ), - onSelected: (PopupMenuItemType result) { - switch (result) { - case PopupMenuItemType.reset: - break; - case PopupMenuItemType.delete: - showDialog( - context: context, - child: AlertDialog( - title: Text('Подтверждение '), - content: SingleChildScrollView( - child: ListBody( - children: [ - Text('удалить учетную запись?'), - ], - ), - ), - actions: [ - TextButton( - child: Text('Отменить'), - onPressed: () { - Navigator.of(context)..pop(); - }, - ), - TextButton( - child: Text( - 'Удалить', - style: TextStyle( - color: BrandColors.red, - ), - ), - onPressed: () { - Navigator.of(context)..pop()..pop(); - }, - ), - ], - )); - break; - } - }, - icon: Icon(Icons.more_vert), - itemBuilder: (BuildContext context) => [ - PopupMenuItem( - value: PopupMenuItemType.reset, - child: Container( - padding: EdgeInsets.only(left: 5), - child: Text('Сбросить пароль'), - ), - ), - PopupMenuItem( - value: PopupMenuItemType.delete, - child: Container( - padding: EdgeInsets.only(left: 5), - child: Text( - 'Удалить', - style: TextStyle(color: BrandColors.red), - ), - ), - ), - ], - ), - ), - ), - Spacer(), - Padding( - padding: EdgeInsets.symmetric( - vertical: 20, - horizontal: 15, - ), - child: BrandText.h1( - user.login, - softWrap: true, - overflow: TextOverflow.ellipsis, - )), - ], - ), ), - SizedBox(height: 20), - Padding( - padding: brandPagePadding2.copyWith(bottom: 20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - BrandText.small('Учетная запись'), - Container( - height: 40, - alignment: Alignment.centerLeft, - child: BrandText.h4('${user.login}@example.com'), - ), - SizedBox(height: 14), - BrandText.small('Пароль'), - Container( - height: 40, - alignment: Alignment.centerLeft, - child: BrandText.h4(user.password), - ), - SizedBox(height: 24), - BrandDivider(), - SizedBox(height: 20), - BrandButton.iconText( - title: 'Отправить реквизиты для входа', - icon: Icon(BrandIcons.share), - onPressed: () {}, - ), - SizedBox(height: 20), - BrandDivider(), - SizedBox(height: 20), - Text( - 'Вам был создан доступ к сервисам с логином и паролем к сервисам:- E-mail с адресом - Менеджер паролей: - Файловое облако: - Видеоконференция - Git сервер '), - ], - ), - ) - ], - ), + ) + ], ); } } - -enum PopupMenuItemType { - reset, - delete, -} diff --git a/lib/utils/crypto.dart b/lib/utils/crypto.dart new file mode 100644 index 0000000000..092f1175f9 --- /dev/null +++ b/lib/utils/crypto.dart @@ -0,0 +1,10 @@ +import 'dart:convert'; + +import 'package:crypto/crypto.dart'; + +String convertToSha512Hash(String text) { + var bytes = utf8.encode(text); + + var hash = sha512.convert(bytes); + return hash.toString(); +} diff --git a/pubspec.lock b/pubspec.lock index 82c5c198a6..58e73f3a31 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,20 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "14.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "0.41.1" archive: dependency: transitive description: @@ -36,6 +50,62 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0-nullsafety.1" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.0" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.5" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.1" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.11" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.5" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.2" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "7.1.0" characters: dependency: transitive description: @@ -50,6 +120,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0-nullsafety.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" clock: dependency: transitive description: @@ -57,6 +141,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0-nullsafety.1" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "3.5.0" collection: dependency: transitive description: @@ -72,7 +163,7 @@ packages: source: hosted version: "2.1.1" crypto: - dependency: transitive + dependency: "direct main" description: name: crypto url: "https://pub.dartlang.org" @@ -84,7 +175,7 @@ packages: name: cubit_form url: "https://pub.dartlang.org" source: hosted - version: "0.0.14" + version: "0.0.15" cupertino_icons: dependency: "direct main" description: @@ -92,6 +183,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.10" + dartx: + dependency: transitive + description: + name: dartx + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.0" + dio: + dependency: "direct main" + description: + name: dio + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.10" easy_localization: dependency: "direct main" description: @@ -134,6 +246,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.2.1" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.11" flutter: dependency: "direct main" description: flutter @@ -158,6 +277,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_secure_storage: + dependency: "direct main" + description: + name: flutter_secure_storage + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.5" flutter_test: dependency: "direct dev" description: flutter @@ -168,6 +294,13 @@ packages: description: flutter source: sdk version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" google_fonts: dependency: "direct main" description: @@ -175,6 +308,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + hive: + dependency: "direct main" + description: + name: hive + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.4+1" + hive_flutter: + dependency: "direct main" + description: + name: hive_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.1" + hive_generator: + dependency: "direct dev" + description: + name: hive_generator + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.2" http: dependency: transitive description: @@ -182,6 +343,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.2" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" http_parser: dependency: transitive description: @@ -203,6 +371,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.16.1" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.4" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.1" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + url: "https://pub.dartlang.org" + source: hosted + version: "3.5.1" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.4" mask_text_input_formatter: dependency: transitive description: @@ -224,6 +427,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0-nullsafety.3" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.7" nested: dependency: transitive description: @@ -231,6 +441,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.4" + node_interop: + dependency: transitive + description: + name: node_interop + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + node_io: + dependency: transitive + description: + name: node_io + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" package_info: dependency: "direct main" description: @@ -308,6 +539,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.3" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" process: dependency: transitive description: @@ -322,6 +560,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.3.2+2" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.7" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" shared_preferences: dependency: transitive description: @@ -364,6 +623,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.0.1+3" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.9" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.3" shortuuid: dependency: transitive description: @@ -376,6 +649,13 @@ packages: description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.10+1" source_span: dependency: transitive description: @@ -397,6 +677,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0-nullsafety.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" string_scanner: dependency: transitive description: @@ -418,6 +705,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.2.19-nullsafety.2" + time: + dependency: transitive + description: + name: time + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.1+3" typed_data: dependency: transitive description: @@ -481,6 +782,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0-nullsafety.3" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.7+15" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" win32: dependency: transitive description: @@ -510,5 +825,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0-110 <2.11.0" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 8c176b10ee..e7feef1c5b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,12 +9,18 @@ environment: dependencies: flutter: sdk: flutter - cubit_form: ^0.0.14 + crypto: ^2.1.5 + cubit_form: ^0.0.15 cupertino_icons: ^1.0.0 + dio: ^3.0.10 easy_localization: ^2.3.3 equatable: ^1.2.5 flutter_bloc: ^6.1.1 + flutter_secure_storage: ^3.3.5 google_fonts: ^1.1.1 + hive: ^1.4.4+1 + hive_flutter: ^0.3.1 + json_annotation: ^3.1.1 package_info: ^0.4.3+2 provider: ^4.3.2+2 url_launcher: ^5.7.10 @@ -22,12 +28,16 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + build_runner: ^1.10.11 flutter_launcher_icons: ^0.8.1 + hive_generator: ^0.8.2 + json_serializable: ^3.5.1 flutter_icons: android: "launcher_icon" ios: true - image_path: "assets/images/icon/logo.png" + image_path_android: "assets/images/icon/logo_android.png" + image_path_ios: "assets/images/icon/logo_ios.png" flutter: uses-material-design: true