From 3dee865926f6e804ed66d74054e0ce8df430b27e Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 26 Oct 2022 17:29:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A9=E8=AE=B0=E8=AF=8D=E6=A0=A1=E9=AA=8C,?= =?UTF-8?q?=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 7 +- assets/images/login_bg.png | Bin 0 -> 17803 bytes lib/main.dart | 5 + lib/models/auth/auth_model.dart | 6 +- lib/services/auth_service.dart | 15 ++- lib/views/auth/create/verify_page.dart | 122 +++++++++++++++++++---- lib/views/auth/import/index_page.dart | 44 +++----- lib/views/auth/index/index_page.dart | 96 ++++++++++++++---- 8 files changed, 217 insertions(+), 78 deletions(-) create mode 100644 assets/images/login_bg.png diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 76699a9..28348e3 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,9 +1,12 @@ - + android:icon="@mipmap/ic_launcher" + android:requestLegacyExternalStorage="true" + tools:replace="android:label"> Agseg7hLm zN~ocUp(9mk`-$(~fA)Oe%-%ES%$Yg-QR9>KtaX>`Zr39Gv6k9pT2@*R2y_{)4$}dF z$iqM&vgC_Yz$dg`x9)>L+#opYzOGN^`iyV$#`4km&bVjM$h4hkI$WK|o%f)C?hh*? z4GSXQk~Z*9Iyx;^A}>xH^T7H6ZJq>kTGCJ7>@dmZ;NXBUlQze!kU3P5Z6tA^do2*cyF*f4{?6LJi%vfZ6!qxf0z3NZ)3%ZpZ- ztg!}ukhJhA^}iU*npFBjbP&Xj3+}#l762^J?{EQ~%}v|`GksMUSNBW6u&kY({QDe) zmX7mq`vQMa-p9LPa=7x6v`(Pbb zU{ppGM18{4K;LjlADl|j=UK7!A#48ug7y4(cAHSsD2 zU{?kc_8!2MlWQ#B+01d`F{2g?#`e0vtfc!-jLj2+&IvaQiw1xdgYhA^BoHlauBlJW(8 z7X7OY6b*C@S0-*uKz9z!IhtiWJp^wysx7! zckknzzrsw@%fIZ>o7EjzD@b@w(q6ZmxioNGdv>^e(fOB{7bluHH>n^|>R9mcEwpr* zkQeZu)syhaiiGbhR~wQ-v|g4;1x=%bDVCpa;<&8zI#wuHs{NabQ=)Z!q2m z@Cebwy-zo@rSx#KFCTxggHyx(iZPB*k%V7!k8nnbGZ@^E&>CtEkU@z=uh#x-LIT|> z42SUS(r1D9Y51jJ-pZQB`Y-#Z1IKVc!{wy;!E!dz(03znzg*0eTdSze7)K7UTZ3DP zGisUXQq3ATKF=;aez?4sHSJTcVtFN!fWE>fmHGe3mTXR>-@~oBwJIr>$=AV`bff{} zrcBr~sKQCSp1eBozF;GW5DIpE`XaP85hIJ`>e)=lcA}}c4|{GDs7vw$3bcpa;G^-| zLAr-4!@TH&fj@FB4Vx2unietj8EI+wVA-Zk5bMt=Y#{cx;zpB3qYG-~IScr16k`Zx zAjJ1$v$y&+)s6+)PC!D{g3Nc^kG?i4$L2pdC!c>U=M%M~En;?Zzr|sm3L$^_Qt9^=&pE13VxppA}F_%+47T&%(kh^E6&%auXBpD+z-=9{@Rgfqd2Y z3Pqu|)QjY!!dI-Ufb&bPxn-#Uf7oA!U+N6#cnEe~Mp-yhmMH!_dVQn`6D~4iCq4Cl z`_sp7X92J0Q_6ng?O<)4V1{p`xGl+sV>dI&4g6e0AugE#b6=&$0*B~NZzpXoEzMI_ z_73oxYEk|$k~qhfNp92M-i-+x4ok&BWT;bGxeQzmy@xE$guhDWft6 z&k1BwG0xUw0)X5~yug)q#uggs44J0mN7mMwi~q|M{-2QT6K|097$-W049U6(HX@JJ ztT9#Sl^nrSS2(R6K zqXiHV!cs`!{r{!42$8IPmEVrDq7Ni?%37hLJvD=% zRr;^}4%bNv&#~uOz%{|F@m+pH?N=5;2+~D)mu}`qm;Mp@(f;?K)w>%ABLP8u?I4&dfZtR~_ z8?qchZg$CPgLZ12{t{PS$IAf?LmE!hgP=01F+L-NiP%bQdEDM2>PYLu{q!_V0YGPC zFtxa|L!uIa1Iy2|a8{@acMk~+`50QuxOMyqv!&LNEAdK7GJ_XTWVLF14Ya~2cg@6X z9Cb9Y*Kvg#k__vh!CHjcGi?Q4!G~Uzl*|YPK+itC#ch%y994bXA`THHI~X7a&FVi% zOB-M$Y1U3hing30hHYs8>?*gN0UKxPr0MNdF|vyt|J9pDEfK= zaLRe$l<9n)@0TKO=C~SY9lumj>H^Y6k}En^xO9)tC5*IwZ3s zVfI6rG<^1W7#*k7n*eLim*Z6O6U>A0)`D%(i4ygVlbYG24!*zpwYdMEOJZ zbOSaALAx(k%IAto?)A$JQj`_Sqd0d%C_SlPY>;xPNwc=WFoUN70uZfIc@&X%fO@c8 zp59(rOb7_G|9zk!snISQB>WUtT`o%eY;Da%3OrH>*mHevI&16dw1jr5U(eUiY8n@R zx%$E~fw<}UJ0}tlw5k?;#{3KHwKe+OF7Hr$_M4+2z$>gdxYS9>%zx*PDGZo9Q%s?P zy?!U4iNaT|eBY$8%Pdig%GZDdC^Mnmx`_wkB;tPs9@)!j@pXDr`C4_)O=2x}*R4^n z+fMmD?koBM>ob#`qmR(#(~SKLl#h)8nSngXN2~Ep?q(}D=c?UqgeF>MCH$U~hIC2Si-Jw+__nBWm!Iy93V3Bz?R4gDy~ z895Vx7bh~~Ja!o!h2WDlL;g-Ns40zz0tv~07~f#gDa2&O8yCOm-z#nwuxSGw1?%db zeQ>4P4TfY7!R__T%}YGyP3TU=*Ygas6T(YN6>`CRr|qpdVu|4HkZkhjxPtR&>@dqW zo&2C2i|m9;vF0w4r=Oddk8}VO$D=rZ6gXG+=HBj`|97C#)f7;f@o+@E!GAIXmiQX! z+fRRwJ6jKzc#u44EUtzHuX$A-#K1RIB8wE=;8(YRL4E=myLI4D#}3!Z6E?b zp1~sAkIv;ng+{KwV-;7v_62$}(YU<>)RF7ko9UNd#wos?^|q~bbJH&u1I8H6jLXsVl66YuHh2I+omQH*gvamZEet+>5MRaU<)10WQKNoYC$ zzRGK7VD^#Bq%jw>4_RoevXIaKwwxvvf%$_eKWb$1F^2`T-W9)qLUDnn$WoxQP2dWf z525LoomHrE5_i@=jCPVdN7IDy@EuB~ZH|p+;iXy5%^Z7V(hEkVE%};B8DJOr_*=tX zEEKahIKVa(1^kU(>^ywc5W0kI-=E)KF8%|deTqFBaHS>6=H$-s0SGP>dp*GbtTQ)t zNS;D>WLS;(w~PVLu-9nZP=i82VC~Hu3nb=;0|6={Tk~$m&Pvk$^+T1`v)Rmp<*v&e z4s?ZYwv@58;a*}wMvngpaXijHx6@(A@6gGSsJGBA%R1(NFp=~Khrl+5mo-~0TU{^V z%Qcu+aGx+k(_f%pw`=8rWZ(W;9Rq1XI5f_wb@Zu4JJ$&w4K43t>l6ptqEL5ZSaZ^( zbY>-Xg4KuEwOUq`m)}?<5B0pLE@f~S8S$Dz4NVH~lo+W6j5+8n<@Egww=tGmsO~TM z{F^>?Nkr)NA%~$RDMnc%Tc?+9L&~T(Sr-(o^Zuo_$krdi1WmB3|4Q4_V|qn*+gcKo z15W}ULuJorwtxrS|MN*2y8Xu&rXhAil5MA@C5a{d($v2AR5HvSZdi-)>391V&xPVK zo*_S4W+kCvggmR_Pz`*l0h_`j9H&Zi&@m1o&SugkA^r6C>J6ofNA8vLsr&yhmOz=s zP%Yg%B`-4)%DmnGVHEohu$K|gFpZGD{4;IXH05-hPga5ofMq~tUhS60*et|j{z5xL zTiA#P&>YYL7=L8tkdHyD09#!C&lc_TfpIK}$q9~^VSecKvL3~=rPXkL*^4vD`I z&{u_ZEYMOe@c31>Gy_s1G$sIc^_>whJwey`%6tv647WWnx$t z@t@Obo0zAhLz~I<6*?sQ5u{+(U!qXhv6=mY^D9dK0;cX+LuT}|UQ*d$;HwjEJp0?# zB*%unROeqo(JN^i-5wOE^}qd_4Q^QW-lyOCUs-thrXA<@y{bl^HL~6Av#jjDrtvd9 z{tPbsE>Bk$SqV5)L-o4~kuXeBs3((g`yl%unKYHCC`7b6jU<)g+23d{sL)Z1=gQ(d zR&Y^47pIAB3%wMoOc8wH>a5T1K4L5-Im6Hu;0(`f+Sydc!d55_hZ`DCahph zEG4}j>eEfDCOepn|Jh1IN8T@`YG#+w!{tCZxC=iuI36YRK7Bse`I409SA*e(Y(5;@ zR8==VKY6a<6|(dI=zt^vAU6tjHO{F_;h8dRkjBHuG(!hMOS|bCOYT~-8&Pyoa3y-& z*}jz%#5q+VMStAVDH(>mK}uLuR@eChgtq;XXW7OMODzjfL%#wt|JB(lFkxN|;d06| zG-@XlyBNw5%1;q{eS3I~jEkH;eh*y5yOaIIyvEW^rn~>esubWwo*_`X>PlJJnkOwB zM~`OiGZT^&GFUQ~^^E0FZBC4np^~{ik-eU{NsDF0N@I&d zxX91r_P&aDU4lE44f1NF{}$#mDw+|7%w7RYo)MgjPz}5gdfukatv5GJ&TI(*a4|9E zsxbuAP0xd#@iIip|5uty@f*@HgyDVaa&wvI@(AZJmi3**48uQVTTlUq{r#?XR#G4Hu5%fjfPdI z)VM09o;Rwggf3gLhL#kE`Tp8!9gARhL&H=%fNJtJ*i{|oa7iKlBrWX_VJJR&lgNU- z+ue5Qj~Ld1XQAUudyYbuL5FtyOoN-jU>}kqNPtKjeK@A>OEcZj*GmWtLz4XicQmJl z*Y(_S5iC8})onFD26ZHbm-yYrxMiFpT)57$Hfs5{boWd|fyU=K?8E}Q&2IubiFdg1 zXD>6Q0=J{F1xU%C}x?W=9Zu zc53B##|b_)%CY!}mm}+MHrt}FskXvaIgi51O882qxaxBo-fZvHPeau`B;d49*JN~5 z=5nLjvI(#AgqA{xPb|m3NsQU>B!;nO|7l4SIUJx-5*6U6`SV0^YxThinR^qaa?+Qf$#+jk{bET$D2-2E4VnY#uVnC1PJo4ppv3)!LBM(JNMXcFc zY8>)@+b#PAGH*Y68*ToKpyx>~epBfhc&l6BM>-54*YecMR)^(Dr**`o z7e+uDG`0pH!uw6`l0a+xS*b)8&7Gf?RaM8Bda^ny&IfhuO`>?to@b!=nK3tN7Y+l> zu3)lj?hJ)}aRP2GUA_MQ|1Kn>nSrvX_+q z+R!W^yI46bTJOz|XF6JkHqcVt7c$S_ zP$wYKcm_Zk-eH%YK=F)0(2lywYOK6+&!kzxkvf3-s1{Qy$nM?C79zyB!IogE&@>RC zMgMfmSOX_h-ESS}JMbGEd3+763-5Ns%{f0V{ELLX5TkDT+zWX4 z{%B9K*j@gnE}tv%WY^T?7=3JD)5?|#JmIJ*D2F;Spn2Q~8VGbciXq8Wo(Hi9oSdP< zy%YU=vjg2h!{S0Dc*}qd_1c~Lz)o6=xPit@CY^#uNXp#hlM6?(+ZqH@$t)Evi{^2uoxDoQYT3SSjtIUXhpgA6~mo8BmM>>cY zS%4lekJG((s_u7bJN|~rfj!|nO6KDySNU3s*d!13^K(_Sqq|8f>ox_v9EB2NW>LwR z5KZy8pfQJ*C>S~TT4nL+-pijZ;zY$1if~jD)L0w2<(6OBU!uu7QI@hCY54enlLX8Uum5_47-wdUMQ`$!Lb{z0~Igx@Y!Tg^%=YYfRdb3fV3~El&SvWUo7Ay zLe#YM|MfeQ*5L+tPC))@2uhz3+(jM>(%Ra^StN?QPT?5J!r16i_&mig>b?KP8g`mJ zZ)GJEO;W1IIhB?m&<`29*(9cDMYC;9`0V+d?HYI-q@5Q`lOu-kdq6oKK-C~Se5O-- zZrJ@pXGvMV#kB?gXmu=-PTyY8Er4NzIgBliN#<1kgIAP@}U$x z=uwkCvN>I3OkTgtCa=a7|I&-i4gHmUnDwP2)$lS1P*C;H)1o;aW2*;}7btFtd?-Oq zPO{MZdc&S8Z>sQ?Y9q^X1;^DoW*#a&GWdX(iu9WWZAPKkgxH;NGvom+{bal%+R~C~ zf{5lTK1f(5(weRvg<9mDp~;N<6$Em5g(*nNd>o7}0eLw`cj|flowT*6(z)Lfp^x0u z8~mA0p6z^Kn#o?*wHqRal$rGoy{{d1;0~#9CmXu)!@c{!lVur1_(Yy_H$hBNR%%YQ zmWFtvA;^oYHOuzgJibkM$%o&-E;TXb&MomwMzCo@jkJqL?(r?lWfvvmg`;s#`UmTy zBehAGKVaAU1{NuwqFBQu6&LSg@stX4>uscxiWLfRibNTO{o!u=weM=xDM-AzWJ-3J zJvj3_8R>GH_zGVv>7Lc;dWzmd+ip3S8)38<=9s|a(Z_^A_;DW-Fx4q# zCbcy;IJN!SO!5AgxzxOjjmzajPm2VyB+F0@*CtZ-N`6H0I+`p@XoNWPHFEOW6<2kN zJP~{%WIpDCcxi`Ub}0GJ8rj(+CSHHiXET)Yo8=*8!oKTYVI8LMEyd?lK1Mz5IhiA8 zHRvu871CGR=9$OkYI=|EA&wOz9rDfD)hMQzuk^higiLiP$Lxn9XlYg^@^oruCfryW zj~bo#`2N4R01ib}FWC?L$EeUhRXa{8V=R6yxsadaSKkb_M0fg~Uvy$WR5E~PTxIID zjc8z~f2!5d`Mt2`5Ct38MsWJIWgaj*guM)}8-^@s!PTlf;@6jfPBV`Nt9K=4ME~!V z-UCO3pIlz&7~F&9b4jM(7<(0?+%*=Nm^5G#QZmY!GIBOjMWySd=Du3=xj3{uS;~nr zhHMj2(}r1c4FV^@H}HWqeFut?^1J}9fOS{@vL7nTZS%hr4)1v2R=iDBf=lA9Q&yhxq}XK1X^ zTgi|qrj0yk7{?0#WSyvQKP1n3%V~X@#~AbD5e6vZT}alG#9ON6^|EE$6v6H;Yt{rC z7wcoKMr2J!wIMu`S~`wbU{lHHNjKZ7_5T#2|0Y zXN7yXX2!1O+rxG26)(aquHH&|&*H1&8v(rPU;n-I_e#}4sbMjTvUCmVhEc`0!7 zVYdcGTEw*{W7pf-{u$xh<7uZyjBmTp zWCyID`_$e&52p7FNRa`tr;>8{VoxT=@s#Ip{Gwq~j!<@mPa~tU8&-o_#+t}ipY&FT z8ti^ER!gAUn{E8;@U)~M#^fqlc-@)?r(_cM4DxqsQUuCBRQFX2BHTih%n9MKZ?ZBD z%S)+D1KN1cz5<<)+R>u$I^9=K4pObgbW1c=^AmCC_Lw@pu)+=paj1hc3e^<4#%K)m z7ax$+0(2RNlZ%G+FuJ(JN#`-ILMFV`+?ktqZt3Mb2c4ezByeQ~W=BU74e0UT7m#sx z)NmtE4l&{u=8~k?E!n6avtNHWnA^kCRpjPH{7tO{E5)h%e<#Bt(J9=HroS7WP2L>#y6a-qvzV{NH(r^j7}flyWYx+F=;KlTn?3Om zZ(;3^o0k}{TZ|idqNNWzHn88q%Zz*3>&-7QIpj|7TT7y$)Xfc$Wq$x4l5T2Q?0lnHJX@DVw9MnY@#-xX+V6BSV| zA|+YYiA;wEKLdVZs52#d{*{YB(!|@Z)RZmegf#m&P?3DUYbPjjBv91drmiB#MD< zd4IZf6Kv`mcqc2nE||P9(8cH~7w-HTxE?g8?Xe+1bhU~xuChrm(K)jYuMd0#A7Gwi z2kWH(M_5gleFS~a=Am^oXV+Q*feG>5Nm{n;la+x@h4 zC3iYY{=f!Gq@*=#vSz1%9vxaq@#I%71>)$X*720!^(JB8%HYqhDxdbuQ?f+KOTdfc zlsHWF++@N^Y6eT7cAju&3Q>wyb!iJ3rVILYn`lncFGp|DHT=XIQ|>$q&FC%@X`6Lb{;;L3onmtXSuwJ#B#pkT zz&F%!r&UMyaaQpW+gGYEyV__k5xXc=Qrp-u&fCUKP<9%oQzVRd0Wk;TJ%es_c`#-p z<7y;aJhTqO1TVfYGFyiEuMXA0e=}A#(qpi~3W*Rq3&JCUPj9)q-10nDj5n}Q^0k61 zso{~41&jwRC@q5H_mbRuLg+t|KqXlT4z+=g<11TX@5f?W)m2^lBLAwPrpDZ7`ShRkV9`u!rXl}WYD zq^ChoI2*$9wsdD%j*w{-Y8|I&da~BEUrLW~H^4h<5*F7}Fe_x#%N|_M@6X$-^M|Dz zWjHUrPX<_%8yXMC67_VF81 z(>Z5%xfPj@qA@F~up+9LLb9?BZGF7a#|%EBBMU=u9&4#XpFGE!LXOCgB7_^&hWz*C zGxGZU6!LO+w9$LCRR$>HPtaWAUIR*&R5RvJ zDu^A;U>}S~Q-Oz(ZEfzNp;)~T23W_#k5ORoU9v9nF2p2QCh8fI@pLg*R$1-O#3Ifol&Uj&;rC{ zmIL1RV@F>yg%;4_NVxs_7chDo^YYbe+CY9IfL+D6BQiI`&`{LcGjJa_uVU&tE%q|w zj7CUcU-MaM*QV@-a;fc!E5@2wlr6hnn~w=U{q_uJf{hO}`3*KJfH1WaAq)OML$6R) z%z*yrfOq}A2gy7Sw`NvoM}f9_5mO(UlRV&Nf&a}4J=lq90s5Yu+{5jhOU-vzpvCb6 z+;xAMt4RU07Ny@`6TLK|V1Rp6f0LPbc}Xlx>H3lJ3P@dqw^_X7%VSzSZi}INX!4B+-c(wz316i2Cvbmf5eq6P@GWI*W z{h%R)_I#eN$*Ah0DP)QXnUuSb?M6QuG?QU+R9_f$vALqak&;ljBu2(ks4Vd>#AL{(qp;!<$cpuRh$(P7Lr)~1R3`u)vD!b z6F}Y&^Fp@7qAOrE4MPfx967Rb2$aW0_A`Z4{n(Mi7(1}krlDk3=(Zb;T#jewFCxg7H3@SWI+L{9avXda1;7M9e{0*bQ^hBw zA)CRPr}ex}o}O1qO~ALxX;q}nPFSExo%FUW!5m(mtgCOp1Gk6!3E`_2!Fyt9dn{(L zWUFl~2>gfCF1|*s4F@LM#vkj`ELL0I8tMa_T9Z}3V+@Nk_R*|O_OVb4h!W$)brZl-tUCrf^&K zfAw$nExRPzaw%X8v2zK|K%oR`PEV`f?I+`$`6GZk#j5oO}JDC56Zmx^5nx1rATXcO1U{6|G1+=8sbs)j84&?G0qD7!No$ z@A-wFTmrjVjDDemKn5XAAM(blBd7JAQ|q ztHzs!Vxob`JAxk`0F3Gg`dCW>5^X?hypwISxtEW9 z!}U0T%oP*-CH2jc%Q$Q*_~opSJnCt;^_suPCtzJ4puYu>MM{(gkD(jz1BSg|#bk%M zq2n%JFQ5pcA|zn>p`}^}6ieY)q-DMEo`!7-C?%f5@XsauhHzV%z4LO2N!rNl9{xR1 zCwzQ{Wmav51sn-A?!?_4sPQu}z_H`rF6}yTzl=gP+{fh@G}<06uA*#ofqKRPcM`H* zwk+j8$q={qC4ca-XYY7sZ;jh^G!irhX_9tesk#v^-=if8WH^VTS60<|9UmZ(pT_aP zV5n&EhKk@$kwx45UZsCRd)*Mb(}OzZsbUc$hCy>6lFWNvkPsv(;R$3x3C>SWz3<^j zrI5C#*bh|uhva&r9BTJXw4`58t?fRemdMXftV}}-+dTDU{x%6IX!*7Fqz@h8t_in) z*rA!ECP_|eW5PWgw2q4fqrZl1-cL;7Z`|Y-I+@|qycMDdO-gkVu*-k&OEX!Isb-Kj z;QD#5ooPKzppyVpEqq$A=NC_;hijWKLEk==vNt81g$A3$rk{D<{)n!j#gB%yq$jge z;c*T|rRb3$jl3sOn=zRO%|pec%mj}?3~-8S_)+!s?yqJZSO`X&2WSH2gcV~S9`llX z)~J1E^kZ)^w9yUt-WPxRwc1e3AAnL+`lIMok(4Zr46FXfg426&E~jCJbYwye%QglE zNYM5E=uXrvvH7Codk6$D+Ab*Tw;z}%8C>4nTn+wF{6eG^>V|YTD{>0@k;H1f-Sgkg7`PbdoR0 zW#)UxBs#&z9RG3&=n-b^OZ!{WK&$OE=q% zX1hDPPL(eVolI88SA1N56Mr+>H)~VArz~*Kt2muhs=>YKi2j;$7ug@X3RkNZ1Ps_S z8ei(k8Fp;c{p#tu{6tv9lRIC$uQ#hoZiw6j<|Q)wa$nU_l0*m5Y;;aAmK?V?g|9v1 z=ohZKhMyU3(TYM97t`l+Yc_FMAq3w^@eXLz=&9n|(6gZDu(~d9hRo}AuWabo_U)Q) z&8k+@Zl40I!`CQ%ULq5=%dhb#dcc9hFi^Mp>-owEGz|gKd6rys3@-$DXlLVqovY@ynTt5LLjg+WR*(Md3~H zvv<9$VVS0$3Y2!{0Bi#U0o`nNgxqx*@|EkQq*+OZ57jzcBr%Zevk`(8<_dee)ldEG%LdV8=$hzVAMAqw6TV z;2x(eM=!q3GvAVOZ@Au&yL!*>VMhyAD!i;nTR0db`#!@DOA1L8jsp%SzFUH+m8Z-VZn>vkKq9m=h3?`) ztjxs#90xsVTfPS5nI;~%tbltC_tyX>tD{(B%M848ibpkuOGC~jWYTG?&u*)p*IF`e zkGl%e)#3yRy#7f_j<#EZ~Mfmok(|eP|lfPeD&T z7+0e;Xg`}VvWag8t52qSz~4{VZawoIS%&Isrpxw6=GCYG7c6cz(U*@a+j`@34TeZH z92&zC!UY=Q+5yXxwIwA^8to|(w!#mL_l=(lCkMAB-$T(U{*TOh|Qod2a14R zEo=tk20z&~{z>oM_4&uYtuMz$q2Ql)a*05Ff=N#9EAeb_%-yI#HI#RVmy(NGjWA}( z>BN@1bocQr?74D5h<4b&lpT_vMtC6mQ@cQzp>fdru}kIh1a^}Db%#|=CvM}$qtDF1 zWON3q$1qUjXf&UxL@C?L?pROQ`*?htPb?%#(HH0< z*DBoG{9pE|GHLTq#gSUzi=qEo;62tho%_MqK}rRi$3r(;Y9xvZ&@)ViNn#Y$arBi8&UDa=F z`y()%`&OBFOX_$G(=PB-N8FLy&Iw@fZR^`F*A!SUhIxADI({S1wx{?_BE}7H%5IeR zYS0zHI%X{O=JS$MbFzF+PnWh7`-{VD@7d%ZK*P&2Qr{b>z>CpZZzd(&uVeF}QME6% z{J~a{Izy>bg?I5(#Y;5|x+QHiB%2$-9EhLtK!OyyGk6vtgyZnC4fomKl(=e+*e!?1 zikd_5&z_eH`iznt%>f!vhCz>%A7!sb?%1b05yQ(Y3(f;`m;Uu{GWaIniRAmM<~n-9 zi}$6y5Kc=2jGWR-4b`szGM@&W@g*Rwb?Hs^e*ZDNuh*BxJ}peA*F{t7_$rV!HHIzK z92)&7pK_Vyi%{tzi{ZPeew_h4O5LQ1C9o&~|`#2nb!D1rsKlb^6u zHt*P*6_aO6ve|Zz7etV$47LHcoM1Tr5GJOXF!)~+7#&+X3|&J};h($qlF$&*Uid(; zvhgNlvq%B`<%D`7zo67nGE6USCacv=`(Q6%mD873zmu7Obrt)(lab+>>+7j8;OAoVC(qO1(J%s1t598vJ3U z>9SE5;d0bII@;q2yblwCpCr_fZGVU96&F1wO+}*CsTuKZcD>Zlfl`TVKJ=b2fhN2x zGGtMRzCf_Bqlnn^q8tfyrQ6hN6yx>|O%s}L7o4U5GUfwhYs~?66?AdRwU;DFv4o8X zWC>kV2Keg-sBWWP=cYPlEI{9QKK{wS*6M71>IsJ-(S@1-#y^6&P3$bgrrfYo zMf8?@S@z1ib$J1WUmw$w=s6B{=hPT_x|TBcoNb3)K5i+a-Pc+YiiL(xfe_lJ$A{>oTN{m6-3GNnU#NJI z+tNeYE91mxEO6D)6=+%e0dpLW^7`qpb(bzV#ToaIa)hA}MCr-i#I3CKoGvozrRF8? zJKM1R+aw%fTOa%LsofQOU)Xrj*_{ym$Sn5<{#Q=D$5|b!TZ4|TM*?H>W%9Or>a|5$ zV0|h4`n-hVMxkM%eh?bIU*5S4@YQWy5K+WCw$ z{J31iT_E4fe;w3fnRs$Nzm@I&D=G&Zp-TQs1^^{b9oH4A!Z?!?SEIrfIioe6X6O4P zcg^W{U-+Y<*+9qdF$V3oQsOouv&w#@wQnU1q?V42oXNofLW1rqIcc~MXz0fFa_nXR zJCtZnc#h-WCYzm3+n=V<_r|W|Py%d~GWPBLQc|r2OnIdX<=-jIQa8WJ3wCkPuA3tY zC8_DgX^GEi|MUn39xal{rcyr*aA<##c&iXr_Z=WAZzk4`y!0s;_3D-EY5ab{pr$W8l*XJi$(wsiNH zLc$V^p{WRoE$TD;ADL?a?PaCz#8?zfiWS4n91{t7!M2VX($z=AULIDR73vjn*%>b2 z>R@qH0i|Je2|M_%1|o}B)V?_qs>mdhwSEs#&JuDLI zC$~25V>;=UD;_2Hu$%#+$W&R6;n!ow-Hy3we7M7jCVcqQ3+aCr>MC=xaN8%Vw-+2%fAg0DE!Hy14E|3%ku{?VA- zTK`d6omcDnv*O^5G{h+iRZm7Sb65icQOc2iF8~{8=zF% z`qaJ2SDFhWy&Ltl82QeCPQkY@i3VS^&Ruc3#Zchyx#SDf`jsIz`V>G~iZ-FlO#T&= zfN_42+_KWCJufU%*9<-|&>_Eu?4Kl+eX$R5gKb` zzr1uex0fO{S`2(mD5o=R=g5!r(b%dlV#7|03~mA1j(t<9@Zxey~Lm- zj7^ew8HT&b7*dSyN3NKPcjcla|EoR(Ui%Y5x&!s}|UH`pym6H|RI%6Z_ zXrhyi`&P>n*#|CtSir zZnK=s&2hCiOmBuCeI0jXWPDy6M|y9B$L7imb%Ww?3)lsXv3eI+hS>=D=+@ZA2{yfc zkTxbodT{{#|9o)-N+U#X$zuy~hI2;)R}!7$XKj4I_!rmNW_Wp#3Ac~!SV%K?WF<<5 zMnv#N9!gXeP7gpIr6Pd~tu!iS(>a zuKhozE%GBu=9&z5fxjZ*F1jxJW!#eC(Ij_how?1pwi4N-uh=7TZq39XNL zuJbd(lG2tjUBJ~;F}t9h51P%*Em{7E$x57hucTN(U;=9}eV)^#i&a9C$1^C^w zHm}VIDzobs$lu=>&hV*mK*`HpyAOXsbOH&SU+NfYD!+n%gwDSK9!jB*bdTQM)dPV{ uT-+~$?meL=0}1rr1c4sPUI4v!kj!5(y0a@C3H*{35d5JQtn7i=tN#H+!nwo% literal 0 HcmV?d00001 diff --git a/lib/main.dart b/lib/main.dart index dfc4a95..1de486b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,6 +3,7 @@ import 'package:chat/configs/themes.dart'; import 'package:chat/controllers/group_controller.dart'; import 'package:chat/controllers/moment_controller.dart'; import 'package:chat/controllers/private_controller.dart'; +import 'package:chat/controllers/publish_controller.dart'; import 'package:chat/controllers/user_controller.dart'; import 'package:chat/routes/app_router.dart'; import 'package:chat/routes/app_routes.dart'; @@ -66,6 +67,10 @@ class MyApp extends StatelessWidget { () => UserController(), fenix: true, ); + Get.lazyPut( + () => PublishController(), + fenix: true, + ); }, ), ); diff --git a/lib/models/auth/auth_model.dart b/lib/models/auth/auth_model.dart index a550862..c359182 100644 --- a/lib/models/auth/auth_model.dart +++ b/lib/models/auth/auth_model.dart @@ -1,20 +1,20 @@ import 'package:chat/models/user_info_model.dart'; class AuthModel { - String accessToken; + String userToken; String userSig; String userID; UserInfoModel userInfo; AuthModel({ - required this.accessToken, + required this.userToken, required this.userID, required this.userSig, required this.userInfo, }); factory AuthModel.fromJson(Map json) => AuthModel( - accessToken: json['access_token'], + userToken: json['access_token'], userID: json['user_id'].toString(), userSig: json['user_sig'], userInfo: UserInfoModel.fromJson(json['user_info']), diff --git a/lib/services/auth_service.dart b/lib/services/auth_service.dart index f6eab6c..7611f6f 100644 --- a/lib/services/auth_service.dart +++ b/lib/services/auth_service.dart @@ -2,6 +2,7 @@ import 'package:chat/models/user_info_model.dart'; import 'package:chat/providers/auth_provider.dart'; import 'package:chat/routes/auth_routes.dart'; import 'package:chat/services/tim_service.dart'; +import 'package:chat/utils/hd_wallet.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:tencent_im_sdk_plugin/tencent_im_sdk_plugin.dart'; @@ -44,19 +45,24 @@ class AuthService extends GetxService { } } - Future login(String address) async { - address = '12dUut3dG5xWi6JPDMjSSK6s2JPcfeKYL1'; + Future login(String mnemonic) async { + String? address = HDWallet.mnemonicToAddress(mnemonic); + + if (address == null) { + return false; + } + var result = await AuthProvider.login(address); if (result != null) { _box.write('userId', result.userID); _box.write('userSig', result.userSig); - _box.write('userToken', result.accessToken); + _box.write('userToken', result.userToken); _box.write('userInfo', result.userInfo.toJson()); userId = result.userID; userSig = result.userSig; - userToken = result.accessToken; + userToken = result.userToken; userInfo.value = result.userInfo; isLogin.value = true; @@ -88,7 +94,6 @@ class AuthService extends GetxService { } Future updateUserInfo(String key, String value) async { - // userInfo.value.nickname = nickname; if (key == 'nickname') { userInfo.value.nickname = value; } else if (key == 'avatar') { diff --git a/lib/views/auth/create/verify_page.dart b/lib/views/auth/create/verify_page.dart index 5f10977..1e7c6f4 100644 --- a/lib/views/auth/create/verify_page.dart +++ b/lib/views/auth/create/verify_page.dart @@ -1,4 +1,6 @@ import 'package:chat/configs/app_colors.dart'; +import 'package:chat/routes/app_routes.dart'; +import 'package:chat/services/auth_service.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -11,13 +13,21 @@ class AuthCreateVerifyPage extends StatefulWidget { class _AuthCreateVerifyPageState extends State { late final List _mnemonicList; + late final List _originList; + List _sureList = List.generate(12, (index) => ''); + @override void initState() { super.initState(); Get.arguments['language']; var m = Get.arguments['mnemonic'] as List; + _originList = List.from(m); m.shuffle(); _mnemonicList = m; + + setState(() { + _sureList = _originList; + }); } @override @@ -26,25 +36,103 @@ class _AuthCreateVerifyPageState extends State { appBar: AppBar( title: const Text('校验助记词'), ), - body: _moArea(_mnemonicList), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + _sureArea(), + const Padding( + padding: EdgeInsets.symmetric(vertical: 8), + child: Text('请按正确顺序点击您所备份的助记词'), + ), + _moArea(_mnemonicList), + const SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + ElevatedButton( + onPressed: () { + setState(() { + _sureList = List.generate(12, (index) => ''); + }); + }, + child: const Text('重新输入'), + ), + ElevatedButton( + onPressed: _originList.join('') == _sureList.join('') + ? () async { + var result = + await AuthService.to.login(_originList.join(' ')); + if (result) { + Get.offAllNamed(AppRoutes.app); + } + } + : null, + child: const Text('确认备份'), + ), + ], + ), + ], + ), + ); + } + + Widget _sureArea() { + return GridView.builder( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 4.5 / 1, + crossAxisSpacing: 8, + mainAxisSpacing: 8, + ), + itemCount: 12, + itemBuilder: (_, i) { + return Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + border: Border.all( + color: AppColors.border, + width: 1, + ), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + '${i + 1}. ${_sureList[i]}', + style: const TextStyle( + fontSize: 16, + ), + ), + ); + }, ); } Widget _moArea(List mnemonic) { - return Padding( - padding: const EdgeInsets.all(16.0), - child: GridView.builder( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 4.5 / 1, - crossAxisSpacing: 8, - mainAxisSpacing: 8, - ), - itemCount: mnemonic.length, - itemBuilder: (_, i) { - return Container( + return GridView.builder( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 4.5 / 1, + crossAxisSpacing: 8, + mainAxisSpacing: 8, + ), + itemCount: mnemonic.length, + itemBuilder: (_, i) { + return InkWell( + onTap: !_sureList.contains(mnemonic[i]) + ? () { + int len = _sureList.where((element) => element != '').length; + setState(() { + _sureList[len] = mnemonic[i]; + }); + } + : null, + child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( + color: _sureList.contains(mnemonic[i]) ? AppColors.primary : null, border: Border.all( color: AppColors.border, width: 1, @@ -52,14 +140,14 @@ class _AuthCreateVerifyPageState extends State { borderRadius: BorderRadius.circular(8), ), child: Text( - '${i + 1}. ${mnemonic[i]}', + mnemonic[i], style: const TextStyle( fontSize: 16, ), ), - ); - }, - ), + ), + ); + }, ); } } diff --git a/lib/views/auth/import/index_page.dart b/lib/views/auth/import/index_page.dart index 87d94c9..d795f9b 100644 --- a/lib/views/auth/import/index_page.dart +++ b/lib/views/auth/import/index_page.dart @@ -1,7 +1,6 @@ import 'package:chat/configs/app_colors.dart'; import 'package:chat/routes/app_routes.dart'; import 'package:chat/services/auth_service.dart'; -import 'package:chat/utils/hd_wallet.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -13,24 +12,7 @@ class AuthImportPage extends StatefulWidget { } class _AuthImportPageState extends State { - final TextEditingController _editingController = TextEditingController(); - - @override - void initState() { - super.initState(); - - setState(() { - _editingController.text = - 'demise sell awesome tragic faith village party elbow lady leopard wrestle civil'; - }); - } - - @override - void dispose() { - _editingController.dispose(); - super.dispose(); - } - + String _mn = ''; @override Widget build(BuildContext context) { return Scaffold( @@ -42,7 +24,6 @@ class _AuthImportPageState extends State { child: Column( children: [ TextField( - controller: _editingController, maxLines: 5, decoration: const InputDecoration( hintText: '请输入您的助记词,以空格分割单词或汉字', @@ -53,21 +34,24 @@ class _AuthImportPageState extends State { ), ), ), + onChanged: (e) { + setState(() { + _mn = e; + }); + }, ), const SizedBox(height: 16), const Text('支持导入所有遵循BIP标准生成的助记词'), const SizedBox(height: 16), ElevatedButton( - onPressed: () async { - String? address = - HDWallet.mnemonicToAddress(_editingController.text); - if (address != null) { - var result = await AuthService.to.login(address); - if (result) { - Get.offAllNamed(AppRoutes.app); - } - } - }, + onPressed: _mn.isNotEmpty + ? () async { + var result = await AuthService.to.login(_mn); + if (result) { + Get.offAllNamed(AppRoutes.app); + } + } + : null, child: const Text('开始导入'), ), ], diff --git a/lib/views/auth/index/index_page.dart b/lib/views/auth/index/index_page.dart index 8c76401..53c22f5 100644 --- a/lib/views/auth/index/index_page.dart +++ b/lib/views/auth/index/index_page.dart @@ -1,3 +1,4 @@ +import 'package:chat/configs/app_colors.dart'; import 'package:chat/routes/auth_routes.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -13,29 +14,82 @@ class _AuthPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: const Text('ZH-CHAT'), - ), - body: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - ElevatedButton( - onPressed: () { - Get.toNamed(AuthRoutes.create); - }, - child: const Text('创建账户'), + body: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + children: [ + const SizedBox(height: 128), + const Text( + 'ZH-CHAT', + style: TextStyle( + fontSize: 48, + fontWeight: FontWeight.bold, + color: AppColors.primary, ), - ElevatedButton( - onPressed: () { - Get.toNamed(AuthRoutes.import); - }, - child: const Text('导入账户'), + ), + const SizedBox(height: 24), + Image.asset( + 'assets/images/login_bg.png', + fit: BoxFit.contain, + color: AppColors.primary, + ), + const SizedBox(height: 48), + Container( + decoration: BoxDecoration( + color: AppColors.active, + borderRadius: BorderRadius.circular(8), + image: const DecorationImage( + image: AssetImage('assets/images/login_bg.png'), + opacity: 0.2, + fit: BoxFit.contain, + alignment: Alignment.topRight, + ), ), - ], - ), - ], + padding: const EdgeInsets.all(24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + '助记词账户', + style: TextStyle( + color: AppColors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 40), + Row( + children: [ + ElevatedButton( + onPressed: () { + Get.toNamed(AuthRoutes.create); + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + AppColors.white, + ), + ), + child: const Text( + '创建账户', + style: TextStyle( + color: AppColors.active, + ), + ), + ), + const SizedBox(width: 16), + ElevatedButton( + onPressed: () { + Get.toNamed(AuthRoutes.import); + }, + child: const Text('导入账户'), + ), + ], + ), + ], + ), + ), + ], + ), ), ); }