From b748e1525eaa80c82264f2937343353022197f79 Mon Sep 17 00:00:00 2001 From: Sun Date: Tue, 28 Sep 2021 14:13:46 +0800 Subject: [PATCH] add domain service UI --- assets/logo/logo_domain.png | Bin 0 -> 27094 bytes lib/apps/chat/add.dart | 4 +- lib/apps/device/page.dart | 1 - lib/apps/domain/page.dart | 284 ++++++++++++++++++++++++++++++++ lib/apps/group_chat/add.dart | 8 +- lib/apps/service/list.dart | 1 + lib/apps/service/models.dart | 6 + lib/l10n/localizations.dart | 12 ++ lib/l10n/localizations_en.dart | 18 ++ lib/l10n/localizations_zh.dart | 18 ++ lib/pages/account_generate.dart | 3 +- lib/pages/account_restore.dart | 1 + lib/widgets/button_text.dart | 2 +- pubspec.yaml | 1 + src/apps/domain/mod.rs | 42 ++++- 15 files changed, 392 insertions(+), 9 deletions(-) create mode 100644 assets/logo/logo_domain.png diff --git a/assets/logo/logo_domain.png b/assets/logo/logo_domain.png new file mode 100644 index 0000000000000000000000000000000000000000..8324e9c9508ff8a3ce60ea9e754ed5b6b8c1cf26 GIT binary patch literal 27094 zcmd3N1yh^f({_SWEI^AEr&w`{yA)cyNO249?kbx043n7l(?El`q8qdq55=<=-KJQE?wY~cc&0vJkmekoM~C>8tRZ4bZSmb z3v1t+k`gNPg@d9JGC$vQSFaM^>71`^2UR6x;^=R>3X=k=lC(=^ey5T;n7nne$BSQb zo;k%CLw%EKbj-C?I+`U5^LB3FKTP+%0Wjnxs>m|_|NPvHYs>FS$a zC^nZ#{C&1Wz#AbCbSHiwLW7iJc^VQRHo+}*vCYtp!Pt-!;O-WG&I(>!DH-p`&OSq0vCcJ5bUG$V2ayDhE}QM! zi15_8%eE>JMs#PH_ZMN%%hx zCseUEx#aKo0>Gen!{-+YB*b(S2IP)T$|uGe$_CawMMl#!eb7{Z^N|uCRH1g*wS5== z>>CIhwG+M3AgGnLCa@m?*^9uGmpD=I3xA8?iugp0=s&>rDU#rI$#~-M4O!JB|#94)Qbj6Ao!#p(}4_iP#kNv!$}dX_S*CgXkNo z{Y_+Dr&?Nma3yL4v404_{(;SmSw4@MBPdw8;=bA})WE$*&Unq!GWU0lW&3Hu)>eH; z9~qOZXpqVYDX_g6oqRQ!nd#xwTtvxM-2Lk|Ps`cgwzso2BXnc8fOMp1)*ZeJG>f*Q3+jK2xj0W#k2PDTcU&zr2@hv>Yp1-YkiU|g$^j-?UUXC<+Y_JBWZx@+rT~#$k#UZ*7;uy@6Xw-dg{_d%pjTh3Pe|^33xa<_jB~r$AIAaWPQC z1}_W^%~mtZ&!8^9duI#Rde*zu)Y4BO)~W1FdoYIXY_hJWtipq>DDm6RpA!hArma7? z?ppy?QQ4W{hp)*)$dG*M8dS1~)KB382!B_}x_4)Pec#rX{fOs89)Jp9HtsO$`WuI4 zDuETii=K+w^9dkL?G9L!mDl*BLGMTCBBS;Re&uOVeW@#tp%uE1$CxjAgDp~H_n(t) zmZVPY0Qb!NywEd({D1K^0QQs6j1P*;wE<8zAiD&EzZiIp8>|Zb7hQ(g$i}n;h6jir z8kV+)CNU1Afj@!Rje_glbC{B|wdR}=yawDeDcnw^Y^1*s&W6KlbYQEB!A!shfq-$p zYBFx5_rQx2rb0Ph!JY<-&Y%vN;FE+m^em7AVcF8rNO6(X_Mw6VZ0h&2g7|(5+q9*= zEkO&xdu`6sf4BgpWX{KFuIC<4q?o$Mh7KU#@Bo$BK@k;|6u&W$$hDKHliV1Y%6iTz z<IDMHs9z-ZYp+HoNOfA@!X1v!LVU=v zo43VP<*VL`f6g|Gd3C6S8OP*+)!OD~4q(@q&c*o2F;r~}0YW%?!x=Km< zNE*O!#J(AL|2d#_vPCe{qEuE8a|W=V8zlqmCZ#yd$9Ktnd@VOkRdh&_h!4!?Wu;-SJslzrx0kXQ3D|{^^1+O>9;KG zlA4;MoZDv$VG8zER6f?J6h!b?jLtv2)s@>;_=*qyE37vh3X_jC#(g-%KD}tmTGr&= zI?49Vd3txjmLKnO#FBorl3{7MmazVkvWwZt9ASE&M#`#0ekQDGskbA6vZ(Ly9J&j= z!jrGSgN1h*nk?#&h1KGJm7F9ByCIeq~*X6Wj2s}o(4Nsi`p_)fB zt?U4VUl$m7yR9DRdBGzje>vi zl6o6Zz$qn>ZmT!LJL40k#XFW5xa8uIH{eDIMO}Y2djB13+ zWw2|~6qf%Fk3R3;&l75ocBd@MVP7S@NnE>Z3@GiDHQ+R27#?8;U z`%I5u5lwCIU8kGdv0@^kMdjSk*Qv~gT6+KT2Jl^JGIIDw?SJt!x{~I>=aJoh*XY5b zJ8hnSa#@|fjro4Nu@HYBK*zG)9N##TG*qAAu-D{b08ek`kYUEc11ZbFAdfPF*p#V! z(e5?`on^!`O~3Y&eLve)f?SQV+~}Ly+Dm|tNeOO8$HcU2LomTMNE zr%_mP|Mxe*nJql9=A%dO`TSw|w^~h!&HmxKNpU`I*ao=Qoc(yg12%zF)=y|Jnn6n&gc>{1c;z~@!vP9KSxynQ z;N@aDIFNr^qej0gVu0)aM~P!-tGxyJ#_WU0WH+BXB~Ajl{C|4g;rFTS4(I8-;Pd86 zef*Sk*gd#W26v@PLE~_$Gi8jU)+;(ONuiuD*#j>g=HeW2j17RpQ2b0>x9h$?=Nb2# zUX@>VV13S|a6 z9qxF;hwFX0hlDdP1t-v9k6*e1FvQ z6vOQ^xoC5}-Fz5!25d2ucxql(uR1`m3T|eyKzkgS`^<>Y_ys*)q(z)*3T+V0U-;rt zQ_1p7zd3qGyaZxI#1x7*Pydrvl;Erl-VPd^7n_>rhB#&+h&t2z;%M z73qkosDVO<--Y|ES zR%dk8U98vpw$MUvNwF=;)DYg^?Coqc&KMw%!w!U5AXL1T=)3P`&Bzg9q z(Uzqo4Cb`S-uEi<(z6l=n(8GTNVeMFAIzE ztophWPZLpU$le1f$GY=spx36{?=f<4{_R#%hR&h83Wgm!aFIgpjK!-*v$10vKB;F2 zxpfkvv>eH#*)C3KwDsWO^*pnvpMTzHK-9Hzei8t^fT0@VL~3p{{%d# z*PaFEW-8+)jW-f>q|JHAt8!gUK*vRy<3U6!n^u#rGtwi{0GY>C0mP72LkAy^f1EFJ zt=eP;S>y`Y_N}j3M>V$kLwnwxu)kDgq$Azsj(EuD?oZ61!hck)uCg06sei}Icy2$p ztuM2x;1d+YVC48-zrd$3R^O;M8Pz^H^nGTPjKn##4+{6e%=wGY3&-Y@0!CmJkBX)w*L?(f{19%m`dedfAkIA*64NY zz>C<`UxajrzP7gjSwiz2gjCx1X~-78N0@2?AXr8~!20#yr;7N8EBX1M6>EJ^S@32g z>gGGqMbi!FhnjuV;ATc;ZBVdkXMV28B^og6tV#=P_udXqrp0SJ7R#^JTa4Q#^;~#g z)9eA72{sxXOzJlWHtLH&{U9XRPrs&gIXqOY)N)Kt8A)EKTp9?e7=;5rd9a|Z%u%gl&fWY7185*mvX*sCcYY&KLz*jAD~Ly74hr|E)gcRl%j z=P@C$A#McPMX^!~-R`VY=SBJXPL+?X*wXq z3Ln#DUAP?oY8lToxi;vzIx*wM7J7|zS9kLB+=7`@bi-h}f7jQ#3Y90?swpIchz0{7=wDG5LDF&=)0V&VF$3M30Xu8Xj5s}qq;S3km999$WHGm)y zXXTgY+{CG%-*vmYu34DnqV(qMiXTfxmv-fJ_!Tj7OyOWE4>R*b)maBc(9GvD=(p0t zlzv&#l-UT%-k-`spT(Ym`l}}9X~{z5@B(6xpZj1zWSP=qBW)qC{?ovjIp#M;qO!+v zazyjwsl1ej@$amYK^ET}eHX!i%O}gIOs4lxzJvSNtOKzNrLd;{etd($zg}T_w@rXX zS}x(xJ08b){Ze^5#`j4KMq`^I-27#^tjCLvHVt1eaz1Px>iA0^so#wg0R83FKPdXy ziG=IN=E5_EBG~Yk2_3N23J#XPa;jdh^bCgP1L8%nHiudYvO{M6mlv2Enb7=%TYMYf zQKMI+Cds*)Qd?O&MSqRsIZSEz`ELW$y;j!30ip4k`g)%Y!AVUA^j}P0y=dT>3BFrb zE7$j2ri3iBoY$K?j+`PntHrJuSygRNcT|y*e+T09!#KfzJRGCtY+0JNR z{sje(I+ktnu$u35vteH=8c4)Do{j0=)GX2_pNu6b+@8Z*1Hmoj<%s`7ussRkhI{e1 zJmha<-y+;%c-xkd4i7_9jhNCtMm#mpyjw#^0-&HvS5iF`8fN0PWm6#L9A3SN-IhbX zEVe2ncOnzRuqjigEq5fkOH((shPs)Tpkw92%wK~H?(WW`C_6HwB;^+Fy7ru+~ z=wn-v;hE$(Z9W&qwPB;!ZR97lt+qV^dx>hwHy(q-LVz`kG+R*YHJ_W=U{H>rZLKkC zga}!XqrbE3Q&|pFR$gv8wwK5QE~nO=;8w7j`ncYZ4*_5h6Okm+nh%#-Nrumlb@*ar>AJ)J6_Gdli>MIKg*|e ziV0r)jGG{5HOZ@KXWTX!G>5ZESm*x>Qe4Vy5_{;nd6dFRaS<}?X5)yJE1I>N_Hnb( z+_JAmt@{-DEXTxbs8fUX@~LwDf-1(-lMlc4R`dfiv)&SU_yfp6D^4e+P=LeMs3&_sM2NBVwNwNeB^V`K@d>$*bXEj=-`?!x3{r(Ou|w z`)nogjrAkLUOlpyHoKEW;3AI(`=|!Xbh!6>wnwc#R=If!s-ECRii~myMsW>C0Q|NQ z(L*Ew(%OS?kVueA&69SujK(b3)qQszIw({9(~QYlzu83XSHNn2zO=c*Mxc!*+>qY+ z3udI4kyl`1-;yy@ZIE|iJ?y#{Dc!0H>*sjgf4*Z=YoxQkp+^yL6sIx7abt=~`GMZr z0nsE2GQ!YO!95W%u0zms2;G-Wvt@Via?~rjx<~;kVSw2ZXG}+E`?5eVHt>t3^Ji*K z!Lj$4-aD6bRfCDjlrKvv->!l*GcUUHk^BAe#%M`oU4C2W1K@SQ?D6t+FA0L4u;16P zJ+lYIjLeQDNtvfcS1CWz76d~Fctt8(NN%+|a)kRIZYOq;$q~x}c{8*wFX6C+$`)EM z<_2lfniryqV}NlIr}A2Hc5qOaaqSN1jTx6WWkcq}xr%-zD(lixWjWh%556y386iNc1S7^6k9#@vt0g}y^73v~Ody#D!9%5qry1C$}p2{CxRKK1Fs^fO#h zDePnPQUJ|?=tHy9DYz&DACQ8~_pq5w>ET)lB#;7pSmcTj%f&cLQfUZd&-bu?SjcX| zMd5#y`ef8Ua$b7ajMT!fEW6EsB6I=HEBq163ooQ8w|#IO^meiLcC!-)jF5%p5+0jIm^rN?>k@ zpY{9{%K*rA{|M|9lc$CRFatEGKfXu9EE7B9+`_%OEzRoJQPGJH`yDEDe{_a_|2Zlr ze!OIsJ<@}N)}iO4e6;L#8+evu7Dmh#*;|Lm079o-n%9M_7I`b;YWk>CA7YVAde%KlHQ;_p?edn7+3n;f!)xBc@=R?p;SKb~kn8sazmdWf3m+{wE825e6MJl+%i3A4-! zP82d`kbeKb>lTUVP^?BCc)iaq6St+S z(RB0H`pXOPb~*i{6u_P*BD{^I7;JFvhV0=7IT9Zz?(KB&4>)dG15I)-QaKcuJ~Hu% ze#h=(OJa{sQ$59V&ZkUf9!W=DBih%M+)18Fakg)wLFqEP#68>9C9(VdxOi!=qyP?- z;&*RzKNt+=E=R{#KPXaG^=gk+m6QNiu~QCZ@=Q%quw%7LsgW)W7UTpr zkMymOQT=ck*^BdKr*N-dAl6#~2^5U`94+1c@aDkmhIuJl)v_O}g#TQdf&LA3XHi}3 z1NgEdC!NG#HEgSUC+feQ4fLHtv<0;|5Aw)i6;I|zvZzS4>)2Jm9A(BJwjWgnu{0u# zGP+2~03hZ;!sD2{r&z0|V9Z4L* z`~x%qk>SkBnd4m==oiY1e9Rz4{*U}Y=))5A)&@<#;y$rDoUhbW@)tBvpW~PjytX(+ zYSCs8^B^`-D*j#eJQ%d7?r`Et=v!a>gATOZVw^nbNT+TF*`%i6{k%d{6SMS9~W+qVJUfWQ z4LI2>5c4S&i9WdUeWAUJhSIh+jVC?Gf~$bSOwj%z zQ{z%!E>IODIJEXk*@laicVwF5iQCiV|z7yW!aO*dKpD1yM~#XE7mQ zuK3Hq>hWIrzCL-}UNag3HmSiZ&sR<^2JoT-a(I7}=BHSP-5%s~>G2^nQXx(lYm34T z_M!`?JomKyuPayf6eqOUItJpEkNFSG7n1pQ%)Z#P5mXFG3nZ^qx|u4nKL&ePe%vB7e`9y* z;;DO8!p!feP_gGl0qEwvf*I&wpW=o-~IC#aHJ2v8{}kSpLUFH+DPA76mY z3|Ec;US8sxKbm#U7yu2X7^wLvzb;iHwH`>p+YBXuxYq8r`UGJqtO9jG!J<=B{I2B@E;!ixV%vDkx)z2;Ot}g^qD72zSDJmFvUPB2gOy=Ag zy{~T!gLQL`BqI!{H9)<~Pr7&5>ZuvTl9x{W*T*(tm^(?7UN&${t-F~49 z3#bX)YM*g2Myq#iZu#Rq{UEyHCIn<@etGwmU7|>raM%{l!^!~Xpv%5)bHwd+Mo>_@ zik)@krLV$RxD=RTh~h+%?y5cIPzhanV@x-b0u<1Jd6*t!Ww*dcIrc(tbYL?ak*Uc(>)t+W*x7{0|RkFv^^)Jr~U zr={sqpq5D?!qZY=F=lw1V8}(>)(ezJh@BnP#97+~dL=?m6x^Gl4mC#Jj}=s9aolEh z!i&4FbidvhG6mpV2_}xA^w4x^_6}Lg?AD1^+RQ(Vo%p%j%-{AbUN&CZnuu0EG}n1u z?iLK&3N0IFVyrO(=&yeF+X4K|#wY~cjenGE@ZATg=S9m@5v6`^GXW@`s#*xHl^Au{ zn#nX*6k2M3Z~o(}rjqvZ77bh$N5o)VC|jB|P{pExTv5+@NrT`o$58sQ)$q2Dkc~Kr zV4%wE;i@Mn8bRK?;|CxM)v$aT1>M%r>QhgX=`h*$EfCQ-%50u+26IEtmJ9eG6yR*+ z8xm3*?10L#JTt}qOx0w2y)wlgy;;Fm@-%GCAPp$vw8N2TEFu;cFRS6pTkRrR^ zFUJ;xFUxaD!wue?osV<@PJQ~kt0rgH%M~}DV_4HxsZtl=8!EPJPR93(W3Op8@RqXI zY2BnJrEq3ZsehEoQw6g@9G|Hp0#V_cnpuf`mD|RXq!B3Z9JtXm07UPUd0*PsUODW$ z{R#60=T{ig8k}f%p+#+)fd0)6FLPo1*V)GH?T?*K!A4b-0`mCenjD+kh%ckRNVu+{ zF@D(OegM2hvTd;y%C(97&=gk*QJ1q?GP$#VSd*AZ zncW#X-TyOE6oFx{IR)T}-4`3V3;4CJT58stG+-f#cI4FYSZht0v1w9bu=x-p%!?Tk0Lw5na(hKUtC1 zeGsWG45fDDB7FD}n~{jXekztfagNvn`ia}fDt^JE!ND(>-<3h@3ka8^E}>Yy<~*d;cSG7U%jr`b07tb_NF)IbM0`Wa8o12M6K1t zZKn0qX3?gYYnZ&r3A}WyVDBg*C7{c~AH-+(^)hasnvaSw{ELogmhGbYN&+1&K~hH5B=GN!3wh zQ&}UJeWS~Dzi0<}ImuT6W~k1n`tk=8 z#*Kk{cM9k+MQp!-+%+@VrbGP~H8sf)qMsQZHiMQBY^HDJneoDr$T) zpemG#3VgqBT!+1**?IDFa)+fxFz`eSLKKOLyje{tYusU}qGfVcuJ+wuA+zcsm3dnf z<&o_;4+~`vM|G$8&F6Edfcds%v`h@bo#B}8KKG8Cr{?28jDkI;RYwfgAAq484~(cS z1@UAMRtk6K2Vsn!f(-xLiqIh|KtJHYg}vad35GwhR421{)Kn0IrO$CGI-o~(n?sf1 z&BhkS_ap%^{8T!mL7n8~;T@jPvxoPJBrs!%xnQfVL$ZNGT~Lmp@{MY2yA^==?nsrPCit86@?X zgGRAG;3pXnnpg59XW^N|^<% z)heR2EB=LYnosKn!0=2cm>~)@B2byvbVn~PH8R_$?QY^~KMMBl?5R1r7x1M;pTy6^*V|$i zxs~M#Ij(9s9;3~`qtweqn!QY8$?nn^bBGG&yPeQ3KI?ToTRmSy$3exJhI~7z{1dtg z4^8fl1EMs7D8~5)Q7s<*e?Jku#t%5BO1>r%Jp`e}&V}`bv|%G=I*D(FiQnleA3q)~ zF*q`qHKmY{6@RdHK1pSg5x!V9oCHx6UpMQGWA#NcQ7ziGaB}*M!W& z{-}Q(B7BaFVP3wre^9j z)!dN-1l4=USnLkXZ~%C7dPgVSOnQ$2cp9tYu?5>8oPkI`1@j}O#-R{(uf-tnvF@F~ z_b&oxIK9&V2LPkDfihecZvy`K9HZa6`^@zGkkpnv;3|pb&!a7KmfJxDAgnST8A|AZ zgl}Y{mdpqPg~%Garq6c2`k)3_Gkm{mRT#`CbE31IzrU3??0v*-OI9jc!=0PQ zU<6prO;@X;pa%yMU?X2}AWOFn+|wZPECOuH9$)?eQ&8pznpHG=bKSV0OelpC@lFcd zOqn#TI+@A8{fQ!U`ekKa++5UWws_Y2G1xjKO9M6MbYX95u|5m=JW?yFH}K4;@a4UP zpl&9tbiH}I<^FfRfx_bQlrjvkMlpXd2NT+ec(Rbuq~{veZ30XC+WT49O5Q&s>7x1n z9D=2yrSNbkzVcdGHD|tzEo|>j1DQpd9>jDdVaLHoxS1&fU@!~BSK7%PpA{;(dakp^ zVPM!0j=lM7RLJi(at4M{{5*#LinUf2@{laHR1?AxcL6dzKw$ zn#ie(66T@g2-3^)!nm0LXk@kOgMAZviwLxnflFsB@E*mKWXhx^Ja`I_>o?v)8jV z7R^dvKfDRxEjbYS$g}0yvy?!;{DyYc2{g`>^U z`IWd%ZmF7y-(AgL1TOW!p5OQa)8)T2{cN|+tHfSF8NYTi>S)b6-M*xI=X8qesqAL~ z52>}3m51T)qd3@_c!GtXKIs$I4#zIDFV~oH(=9B-HoM`o zm&Lw{@oie39!B7FzUZKx?(k3B0`#m5|($7!ME=dSr4{w6Ub%SJ7@PIxnm za}io6Bm+YaA#*ykcbdl}HYo!K=w|PY>wpj?Bp`s=+r36=@AxcwI%p4_+{a59MQJhe zwy)}e_($wBHH`_J7T8Cj_t8w^1Q_XvM*>G00M*`6UdpBb}pPBOO@C5-gXJ|4HU#5^|HjK1rDN}##&m$ z_%B>)vN&Bt+)k8l>EMaCP~N;;iluJ#T;5J6xn}(&F6fZ1HNWf6y!~_OQ0aRRQz42G z3sD{V{z@LVFj>6{nS1qxJ#Mbidr1vDu)&N`IWglRIDg!rb5tYaveW#4JqdDT>4s

T-FaupRC|>*;U3ZlS&a;KQ@{#DLx{{F`8bNiTkmQd~dMwMRrY@%F_XU8S271 z#s@Qm$w%04iv#2o7;jwbT}}~PigfV#w@!In{ETCd>9h0{KJIAh^Wm5ri~g{JKd@oc zU~M@L=Wo~&KQJXC$5q-o9R}W{)1Ibv*e*(UTrjR`;b+Xd`HI{4uG^K3MjzpK&Lq1Y zaf3IS^L{s%{|yWi1LIo@tPXwA-|P;lqV!S>)Fhajy$zF}Z?9cs*mEnvgodKduRP7B zkp8?`o_Wo%urY6EAGBqtNm;5%Br}gyOU_j$ka9@T6i4biI3YMS6GFRrZgZ2d5dNM8 z(s?m8GBEpCnpN$`%RGv(&&)p4YA<^%{wzRX-I}YZ!63sUp#=)x_UoU&a8o)pOD#6Y z{@Hlh1xx+iRjv#2^+IhjcYoKk+FFdhol#2?0O^JeE^EnPfR#-3Xzq+E%DRK+Uhp@> zWXd0jD_b#|O9%`&wLwWrLJetxLC>gRFf>zf+Jtw^ke=C~J*xDof}9`4`djE*=Hk_h z$!XI;e|_3%`An>ql=bQ1lsd5emO3crUf3%7X;INK8*DbXDn}uMh4y{XiGg4MBZ9;O z6R9juq*?nQ0zPF<+8a4Vo7s$}2zD2CNX&~{H#Ra)qHaeJuf6U!AVytdXdJh#dETymsP?gKo(`DyL$-fvw8hn$im?+#&%rZ(gX@FKILt~X{wUX z2y{j(dBfkXAVZWXLUohA7PfusMc7;67buG@8*;U(fTq*h_oxLre$i>Tfg2APK;O_5 zIeOUX&6G&^{RSKqGnrYY1nDZh)>8)eVeipP(FmCMQNl#17RWfGJmJ=0gTQA!@9ff7 zT>y@zzcspl3bB~eWP{ie%}M4{HYq{mkKp$3l1#Sm@GK}np`_tAAsIQfWx$|LSc+x5 zf5NVqJgn6RG0Jf)+9LHM=GpGxKXRFP?KD4zwOvSWqXcvETqb#it#y9ZADX7`BLCx4 z5!6@iTf6d7x$HT^rhI?&Zo!U5Ig*#9j=jT41Yqc1YaMw^_tJb+te3o~Y{k|<{FpvG z8#JeCqubtVd00?(x_jPaUfpqnj=Duxyn{MqRH+BTNfT)qe^B52S-kd$7y6!k zDa@uqM(?+7PE{u8f^RC*0}6l36#92%R{8t}@8k|YWgqj12;Fa)M%eNip~>jj26$9W z`{dowyRz8o8Hg`SXyw3{%x$)6O6L^>!|UbLU2ys^ zoOR8|nIEF>kxsjpZLx*-4k1!H(ToI4)#&L$%s*bZ0r1?7G8PWR@s=uk*r(a$V-9uNRhZV}Tf-xWi;|Bw-1rPny*-Be&5 z(_m3L-OvTr%5BYoHi8)33FEHW5&Q_G@(IOmSVKblWW|xv&?z&`X%=XNX3|8Jx?W8} zYl6^vh-WH+iAg2l91Ag3^C)W~*1QIV!r)Ba4*UV|jl^RJ(E^n!O4kWBW_Szc2`-P# z^+*O3r!LXPQQFRamY{MuLU_Haavp2u1-1f-#s|#lUUYg^h`&~+mQ4xjwl@$-InBCR z{$_!6IVnMoF6AeMPO1eHKYtomENvl04VrBV`cnRUW!$%wVaJm0nOt(zqCd?I8DNt> zBN=$R;tqjd$?QoeZsHwy<@Ykd?k)(3-~!y&!*K{fXw&fd1=O4U`r?xPyceLE5x&Eb zVf!(SxXRY_R2*mVKj#3;K_Hf4YRT1O1X6hKIgt~tiGQ4mdvt&wC`lIFa$FdKmEuQy zNIez*@%qCo=c_Trlok#~^|NXnjXC}!f&pExzBk=n3UKFMpa^GCeRIh?c}5`B-hGUs zOAW6FFtx3@SI6Z0oBOwmLV@Mn=(*l%`VUF^uZhnQFGS=sJTd}PMh}%PJ59tF#eS`c z3xwXx8X(DLKOT6ZGU=MptQfk8(&y-M!=Sz_01!Y?umJf1JBWP=1Kuf9a8Ts!>%i%~ z)u|fWpnc)YoVLvVHWFFI6ZKqrl8nosd?{4rHEfHVsgJ9Lgyllj0t0M5lk_y^!v^^y zzo-h(KCThNFBpM6>Q;Q}AJM61dF?T)7B(H#Ia z=j(tDg1*q+uJbeB#w@7bF1ss|0v1obApxWXBbHB{`@5_2n`AcmL;Av^hh3RS%q$oF zq?1lp#uQEY`IcIAPb!sisNHuSp0n0{p6mYsrZjmiTp(x_>(Q< zOV^pZaQHZ^2!I6lQjYTf6cWLg+U>j$XsE+of;V*aIUR)xnY3az>HKc7WkzewdbpA) zYftYHjXfuK;lI(Hv0T;)_!jNBDB}@{pSo{jaz6>uEq{Wc70s}So_ek>sJ;PkY}x$^ zmv{~#Itbc}OQD8h%>X;lImKHhrurSdqCT&ag5;_wJ0g-AF|V8vWj}o$97O!*2BtQ zl}P+9*3P3Jjg+C@eQ%{tkeN3n4I8e_TErs{|D%Jppax%BPA?*FMFEv~TH{hNJlyjB z414;2-*?JWLTvX_x!3iA(L$Oj1?KM}Vi!l9EcO+eV(#+IZ|0A1K86?G)q~kgOR(qq z=)iE~EnH{gM;QEABSh^)B)VKhQTVE zsg+WAw zu>0K5LgodhCG5Ib5zazucqD?8xmnm+`TtXFj}vlS{~kWrA9uGO3yRQtw4B1mXOH!A z0w5Rgtyy$rty%7)!P>QcUy?f->7WtOV=5|}S@s~pN5VuU&>^^QYxKj_lwcOM#mW- z%(tA$L=^CPDkguMi`+O>3jpsOBm`;{Ykl*R0b!NtiEIiYF{9_$Vl=k71hQ5r|2Etz zP3m&O;pX}Lhmz!A5?F=mNRnJR#V*!b{2%*3>I`Jgf*8fgiES^0UVLtM4XiITlKy~O zie8FCJz+DHUh~mxiOfYNk*R2%hzMMk0@-scWKN_02GSc5VJ1ppURfYmyNGx$X)^Yr z`G3uQ^+Qz6`}SG7yBj0~QDR|1LO?)T6qZoBmT*^6kdg(YI|Npw8y>nlL_$hLx5{??3VWJZJLE9dq5+J;VH&q$fY~>ZeAU(g_9(w|!Iaz~OlN+SC+#NdtJ=diWPj zz(10sJ2@}XDzaI29~bx+Fv7_k*$8Z7_Ksc?pZlyz)BTV0#wj_J{`8Q|*=%P&L)CF z-#}j-NMhaKEHB_#(5F0@fDPXF%U%BRP{HF_k+0elF=2{N%r~1fN|sdKYp_Uug)|@M z`vXZs9+Rc_?}C_D!#MuyNXJg?@_&yFflk5(Q`pab17Oe?>FAK+Tx;P9L!T=A-7ql* z+TU3&bk{x@Zsw15%}tb|L0~EF62__RTlCcR(I~;n3>B=GLXRS#?%Lr8At6aab2aXs z7c4L_!b}^2Gqnv;U=d79?v)TvEGMd9Z>>XoJ81`@(mMjiC&ZDN8FsShq`0GKGZ1(@ zAQwz!ycB;WAQ5FW_kjvsspGl(xle{O_!7P3ODdtP4d!L-0Yp51WY)JRj2G>`Hc2C7 zaLsRPjt`zBvEFh~kKpHY7p!L>)|pq**6TeMWpl;~V5N3Vt1WWa*U4afC|?vag53bf z#|cGI>zFr18M_*dnQR1KZZhWq9Tn27I(%5zn0Qpsh|&r!7Z;pj5==-0Gq(u=8!Atn z&tx1_SK(!iZ!RN%GQ4x6F@$*f%HtGbb5Vu_fQCSP73*9&bf4QLS$tmP7&mJ!7Tiz% zynt50kkRY3N!ARtZd)ud+>XisQX7a2VV6`xi^E>pZ}OmbhQEa8cRP)&9%LB0i@?5K zaf&=sN9+$Av25{S$^#y2OCGaoR{Bk= z*v5@TWPTldCA0Y#Ot15Cq$2T6LF=H^fkzN0?lYS2fA?qA?E*vgG*u}%aeuT&s>HZ1 zWcKEb2t|fhd6x8gy}FeYVb#D}#n{WFXeg*!j@X{>GxyE|QUDS!)^a78^iY&wWWC^+ zt@R&5czr8Y=zk%2GB#Gf3ST4MC~Vn_lgDxQ)ldQ^pM7^2Ssm@P}x4JW{jpx*0%(Zwg`FBhotx`zZc(#A{vGPB9N`T?{ zYdcBza_e+1wv zA-WKka#~#ts^%Rhx8yDqToQ2oGFA*~FOOqW%f&^+rF@^O%C0e#hCdfmL-Uq?Myxtl zOLRl#uX04arG4tj}iUjtV4Ey%IJEq11b0RtTa(4+KSimvc=r;E&DyH&|~sN{#epVZwP4sx17Hd zSLJ<=kN-$mxQe0)azq`sI-Z*Eh3y6&F3|M_695%Q&{3HrU+c_79fb~xw!g0gy&c_O znlrDM-~U4aRJKYGx~*5DSPIj;6LlOM2e(%Q05ginK~5IZIhTlf+&a#-X(epU^IA9? z_Ep*El;pYJCj5CmrRDH*5`u)^R2R1k#C9dd>CITP6p%hYaXzauJ8&!)4Ac<|$9=-s zR}C}-?-fa=M?)Y4Y>V9mn%d-{t;YK5{Ot}%_9^mAYTSDglhNhgaN&`6{%=F)iR~zs z@Nw>GrT%yPkA?I-89CNOfad?ytN9lthvuxnnx}xEIiBR$KccIiQqE4)X&dXoqs|aw zRHI10IPmX~=$;|0myytMqmz7bZ{_)0XIbdK@Yw{vMCA4MFXDl((WK0;gxDBzV2 z&)Byoy?Z7Mt*HA?hz-S*KREEm!4NvO)BDH~!(A8rYvjKd%UslmkQe$7&^1a)i$j{_ zF(fZGAL?$hPEJGxtwLmY<7nMTF}K>H=VS30&7Qq@PgBC{d%D0ThW(ZpT^o-<8ZIUe z5?95)^kM^uzhRV%(|8i|zQacgZ#dR?eGbh(-2}YQUt$#ga39m#ky`S(YeWO#l_$u= z1)w?p@cV>xFh-^Mh72I^#OQ1=8h=cJ^&ov;nxw-& z9)qWPzOa*4Wgm(iv_j5U!3})~qgP+YWemiXgT%khEprbGU1Q?P5^QT#~&%Mm4Z1hNGmy=T@{?}l=Pn0%{So2+_UU|Bhe5U zKTarrGG{O=T$VU^{Q8x6H_~<96$eQXEsJXZX8hm_qhuY=MITK^Z0RD^`18>U9xv1n zhW-NPPO;jE9r+V}kdWJ?cf6fWH*{k73jBfQsmiu5AOt}$nsz?0a_hsmT3{hjI~H7*+QRT+2&Bosfsn z0B05Ss}tW~0c;c!i1qgB;PxEC)5*}Y!!LX-c~+qC^rkjP_B|lK8o7v>J0EKCgIMfA&0yW`ee)C{;GAAsi?@rxVM94+0Z-mVy6q!_9BVY z8T`|!9kKIvNiX%7`;&*TevLA)gM+#U07M{h~3W$w9FHi!@ikP4xdC-p}^ZlY>dpDInJt~V?q36Yj_`*yp_5@oOGF^ zQij%UjGh*OmBR5!C4SPOgJtS*g;1dOr(tpbsvCELL{CMZ(s#R5!lv}m;^EyMM7DUr zs88wfgZF%63hS!7V9Mp=9E^3P%|KFXJJhyWca%>F>YM)`GZ!GtNSq4|+iYOO zbY=Z)RH$&cof1Tk>v(eeP{aLsFK&fXQKhufSv;yt(h(tFGjsA>_b4>dAMa?`EK+#u zE?;rJ$HoVQ$0&Bam7&-{JaRnS5=ywj)Q0;voRr@$QwPfoD-PZ*&HIcL=U?InL46B$ z!A@gQ64J3=@?0i~ri;`hf?m~__`Wp+!Fmxe)5iNQ9-fYxrJbgr#;klZ=gxCQO_lz{ ze1KDuRuULT&{yZRmP|i7QJZJ@|oYC)@ek#5z z#cpiVr35V*3D=RMs}jqC-S6gH*PFLC8om+`N7dhy%b@d23qMioteC8C-zmF~%}gwZ z*YI3wGV?`(TfUi|rlRpQi!TWY{=^8whWK0y4`;@XBW#)6(n6C@tgiaRG(v!*?xsF@ zE-N_syAAHwlbw1P)`{|#F_!7;Y2&LDx3Yh2-~a*6Wj?&jJx*JYE#vlkh)y#qve{=x zRxX|bs_J^*tRPCce+ar}VR&dg=rv&Y9)k<;R%frP!QqO#_JnsB!solF^ET^zCx384 zHc3y(HP$OFcC5yTY|uRH$pMllh1ThdJfas7gzw9JMCFoEW!}%9OtuRYb7G+t&Rzl4 zZjZ3H&P&1k=N*H2;_V65Cjq=a_;p?h7^ZMeP!PWNw9!aAL9n#Zwtsrl!R>or3P6n2 zj3kYm)`!0dl|9}zyZ57fEuk@~Zq1KBW9LnbDz1o=Q?`{xAUvHYxTkDr48n4sf!|#V z4}#*qW$Laa<6fMd7jw_^DQnj=24%W%8XiaVHT7cL+8pM8>xK_oUm5*oYaQ!(W~pQG z5FPe&6o-bR)#Qt|NFijY;zg3y5-m<>`|2qX_9{d*ExIZRt@ZR(x>Yb_g%Jpw3t=!8 zlmArd$8W`yFgG~o$MHHfjXs?y8w``Ognb7^b|vCcn|HP_l$8PWJUj^8EVTu6URJw# zz(>J77r%8a%Injy;|yNlSAUK{3Y<}vt1Rb*`-C*)Q0VzWIA;G>WWZoe`dQD`OO~u$ z&qvWmTyG59Y3Bcx5S)=Z!p8NxTS82V&Ot|L`ZP|Xqh{iNh4>Q)KBe~cQ;uuU4FhW8 zP*uKog+2%gfxKUAO9FM;-;h-;Y@zISigRVn;%8zE5v^ zp1TQ6@u}c#;pQX?JRk{Xt&(fE9PVzJv^u(n3O&fSH9hB~nBO{;1TQ-zf_R*m8k>oz zSVtwox=rj1>7TGio|?ue^5>n=1>W*Wb9%K+t{y^Bq0JRFQR*~IPZa)2>8ax~eXY|7 z?UV3yTdy~C@UY56zrsL%cn41}gOY|2BHJ(_kc$+twnTut+pjjE!lIMWy| zf)nNyHm2e_Z5-jHe?xGH5uxoDyh)w>Nb*hpvPOt`ermG@ge&eGE0sv-KI^<+s!x{a;(e*?C>vqkKvZ_77 zFfrr6jx?kcS#*GRm}s3pl){H8_+m@FuJ|X6Xt{qszw*JiKQghZf9pjD!9<1iFr>zf zpQLfluAL%FkTYVyOS>mM`xbqbHo0#)i7WHh7w0EFf%mYdrstBr0 z-hP>S9;wTAlCO3iRd^8QZC<65*5&*ETCvd*Lk1T|V+rpXQsVhX%~EY$Z?KjuS1flP zjzEx9k&zX8w7cYlwB3beO%zKN=4;QId9R7Vh2)`Ie;#Bphv)7@hGjKXOvKvg10#K` zpA%`X$db38|M?T$Dw57u>x_)Va>@3pfY|@KrhZ*#=IO`TAghhQSA2mNtWc2#HL>{f z0tMN!`wJL3x_oDLmX-}shB}K6&f{}4|LKZQ$_Hwe*&oBF#UDs_ud<59t^VD2tR~Oxz$nKIO(~Xn71oj z`GajGY6TfFzVGU1(j=I+zP5O+vizQJN7CZ7WpeytHtr07fq0l;69$C7@^UYAo+lU&KZjBc)$!(!uo459aF=po}#6H zA9ex(e4{5g8IU3ST5fBPTxy~#ju7XzI4zv14t^#uZMDk&^I)g7)LQDUzeKiD0&)Cb z6f5@cZ5&kI@Jy))qH^NDz7q(5DRItk>?Tx~{tyHL$&$Gk+;nBe{KCGz>lS>IZNVG* zLBqOhtLep}A5{d=0scA7H2gWf{e-p8%MWa!enhc33GJc6)=uO21_eD*R|+iwc8WAL z4j)i-OVkiaUt=1|NMNZ4U%AMP&zFH4%p`stXYty$G z4cUS6A`4q)OKcM8K3nPU^bb$V5f=;nnT2eQRcKeL_p-izK9`;cLoB>4!=r z)Wh0tNc-49_&te-)sNM>&FG>{s;VAe#yjN~f@V7btOKZCrXD>PaW;VI-DSM}Rjf2a z!J3F7tEX^^(fGaa=9F$iY(b_XL*w*WP)ct5V}q{@w{=eWOq|r~<3KSt6tmQ|+B+Jt z_&Vh&c91D>;E}@y`FjHEbqn;yw^wvC)E2l@#**FCX(Y_ExT@_@zMUV>=cDzci7c?u z-O?as{YKu0D3+zwrYFNb#GQtFO^h7$<=etWvL6}}c3DeoQ_gC5>5K|By)20bn^Vws zJ%@6)8VxjaI7QivC6E$djkxD5*iGS?@v+!51pC%H<qy;4aeftkJ&W&KSH&J%^vG1Fla!8Na`ku4Re6pE79kntp);p@4e7rAWSxJQ3@-7i`jD)0H_nkqn0a9Nc!IF;uO7U|!l|E;O?XQC{~6CH z9vL8QoHlB6pe5j$R@ z43dLSm%V`&UKZ&G82)sgFGUN=mO4jBAcU~DY!kz9HZGd2jjVj9I`lHHkAU9`wBR_i}y-K6g-kyQ6GEVL|s*rsb-w|UO1Ubm6g ztR6;Eaqj&D;X_>AA3w}m8m#F@T>NxEUS^`TxaL0#Uu*r?x{?Q=$!`@-{ckt;Fb?Os zzcjuZ84wv1=C)s7-DK$Ib!~V0AMqkcXRIn>Vb>MdmU&2A@P`NArb~w^T`EztnLx()UQpi>Q!nuz4D@V)7SfY0hw(Flk5bER~O>_%va=2 zwfn<0aaxgg@zFdh19d3T(l4>bhLSj$e#yf;hZ5I^ZGv(ALx$o-hf>&&*lVA~Sf^UC zAI)Bksb`apYAAitQr5Qantw!}-mSO3m|%iCqCL2&ru=~rvDMqlIo0xlZ%Q&ViWJsB z+!b*Mkr^9fIrc%=b3uhO6b2xg&b7kJ2B4gA8@ws@%OV}c2TidpG;3_W7+LjAg8OIV zMo+zCWTTNczS3au5jz<-dzx`#dx!sAcv1?yfq+}Cv75t3SIU)}X;z|#3Ukd4DMi1{1CkZy=^v^=2~Y9aPgl!7wl&P!t_7l9>O})PCarZxc|CTDJ#t7# zRlJO>7SX6&pkbCC^X5g>honIowwVL3vUjy-?s&_hz)xzzo>{$>ml^zM2D~-ksKp9hCW@(QMHtfcsu z8F0U8Wu*+BCh!$VC5kXRa5%72Jjv2Ke#8Eif?a*-3;ypNz?5ZVjeXX!vN_{(6jd3{ zj{|u(#9h$0BC<98k6T;*HyGz??9tQ`O}Y%5mIt$KwCn7=A3qRgSESZLfbNSIVdQ&h z2FDdUwc~H?6;FzGc`9jzHO7GLckNRC=+)u{ffKEPwT))IT5konK)5qOXaxLvqUw%lB$Lf6C}*;{k8nqv4`r{wlB69x^uEn#OzD+;Wp{yOvJALK9YNqTRHyvgL0im?j+~E+kIW1))zAPU zrBbms z#&)E=T1it@DF}0vW=L}M;AjfgYI}q5^6mEDtrA^LB7GUSCk+Yp11x`_rYAPpb6q_W zRX5gOXRSQr^`YFIxS+XLm*IAn+7q)`#%kiM_IkBn82Lh9Bo ztx;s@I*t@3WF2Ac8&~1*D{9}224WPFgmhvKveZhJ>&Rj?6aBC{bn%ymp-jRK-l!JP zEN739#=9&o?qLC0CV!~QdorIrXSVD(8IEb~s$KSl$o$?@E$kHCwF%SQpSGT)o7PH) z{D+J#!#{ktWejjEMS`09Az#&if{)ITH1PZ#S88avlO@-XcXRlGTJCX7yxysdf4;^> z3`r|`rtjC}x_)!p7o|N`R4C+^Hv~15pUsYaOulr+b?c|VZaMJ1XRHyQe7kS&9_EV) z`voN=Mg!3nMQFe)eVpOSCEd4@c2P}mEgrJMzK5Z2)f07U-?{4T9lN-yd)YnFGukTxO#gTZ0-9LEWyJI_KB;2~wL#TA z6x$^6lBj>>o@Oa&n}oBgMU~=(f8|}*3OsPn4C1uzWV5c}{n^3b05v%HO@?ddS*^H!l8Kl>~i)-76b{qs@_JoZqa%K|rIUO)g&;dQbWy*?i3 z#c-JS;}YmBOCuv0^0t+<_vH%D6_MONX?)Mwb+^EnDVDh(-yh6H7PvG?t^Fw}rtE6D zt`ewe!@jQ_K1p&P9K=%O|Ea*hdXzv`0JtR>`}4UB7=)vN9~-BJbtMRM)0Ax(pJ-4> z!QFdvHwj}dn8vy?02?54l(6 z6W==i`jhI$9n-#dm~`t@KeuO zln8ZJ2!v%FPMZ3D`15*`#Is9R{72i~eq3pOUEhsLAXjkm;rnw%dogC|!Wwb?<*-S) zjXk?WF;u9H-79L+zxml2R*6rDf6$fpR%2r=zo?3|1r1Q~*48!V-o1=R`pO_`e@1_`q#!pbcG_L-dUcw_L31#*+li4Kt=XMIp3Pq(Q{C zM>HO3esy)xX65sPs+^WA(#puw{GNHotQsNe^fNC(X^|n`IqH!$332N`d*0U#RWKKR zG(8K;m7V#{o3=PhC0+bCz;MKN!_JmoU7B0v|H;`f*yGb=Q;ZQ=2p(&g9z3qY8*8DIV9Ae0PWA?1H~$ z3OnawONn<8D^t-<7(^7@;3~X4(3=cP1`kLmVbt$=<1{Vh_QqAYDMyjX=;_!y4_;7} z-1GUcXpyZ2vpC!Kj9c`UrThKJ%q-=*0t(5^yFu^2#f7sZWp2sKTn;%I^S4_I*%{8` znwe776nFw07O*^Wg!tIF`<{5)-Sg&_+w@d49zc{PN>7EB)gFT=2 z)wOHl4P(C#ZbyXf;~f)`>18a;!b=OL4JtT%9CXRHO(}dIr-rktBGXAT7k7?!Ik~zN zx_waht;-?HvitCFVGQfZ|1`I8Q9V7luO4%beHi@&VkUUJdX=YAlxEoLfmmZC7+2ou z4TO;;zC9E^LqQ8<7Ub>kBVDaoQv86kU5b^sS@+dF z3mf`RhQVtqFkzVfU{fw$-UIz(^EAb$nC|1G zzu&D}5r1q&SDzu^*BAcH7SIZsjuC|v%}7|-3rk}g>Io_*UbIzaxr}?@1Xc@2YWVHk zPF$h+kKn>*f^ow`Hra3bhSZqV_ZsVwf$en;3kzwTg#s}!C2`ikx%Noed>VV8J@KNg2N!FxZ9LNC42xlV*;lPO!W0S)?yLd8bGHh^S3)v&rS@F$Q9INYTv^4r2@| zTxR9;J=_MIeaqxGy?z~wN7RoHOB6rX4H*eY)&-GmZ@$0S-7XNyduU3orUyfXemA2# zPT67(PoA=t@Q?iXXz{)TiEt@owtieI+@#qD*4V_@q|=-&!Tj6k>L#?;03^fVEfE9a z^5v76mUvZon;SeI%T3a>gt27oV^xP(J ztL#u-@@C~X{KQLBeJ>iOM5~JLcFO*$YLE`=NoTiir`JR8@KB3mDLgibr(d@0!*51+ zIQhkOyr^ILPlC|BzTJ{c#}n+1Wsc8<2W)A*AGNx{8>Y;(7$fJh6D;9BwzL#KrGX(o z1BowJUu+l(Ad*-eZGdJ>2(25P{0>A$yPI4;Dr~OOlI(XYTO#;g3TJWnkJw?~UmVAR z9k&c<9JJTwX}c>9UJkoF9qhI**wetVc%QL6BrkF7Bsfz*Us3ALG+~oF^@4$`g}lQX zh=%_x$Mp|pXrYWW2-{>#J$!%Aa!5rnZ5pG+U#~ap*rwxcu1`OSs)%M*=K(!?=46)!`V+Z;vW&#&4&7MFuO58 z4(>&))+y+QRg#DH1nv=-!>NUX3G=On5<M3uVG zNsW>jHl?&ES>E?Zm{J~#sH;c}|9?A+le`Oy!jXlY&q~$cR)O~hSwzek=o-kDrs^^> zzYsE2Sj;NHh2?Q0JWI6B=$I3s_@$G7i { UserInfo(app: 'add-friend', id: account.id, name: account.name, addr: Global.addr) ), - child: Text(lang.myQrcode, style: TextStyle(fontSize: 16.0)), + child: Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Text(lang.myQrcode, style: TextStyle(fontSize: 16.0))), ), ] ), diff --git a/lib/apps/device/page.dart b/lib/apps/device/page.dart index b969766..f6ce808 100644 --- a/lib/apps/device/page.dart +++ b/lib/apps/device/page.dart @@ -46,7 +46,6 @@ class _DevicesPageState extends State { } }, text: lang.send, - width: 600.0 ), ] )); diff --git a/lib/apps/domain/page.dart b/lib/apps/domain/page.dart index e69de29..75a5bd9 100644 --- a/lib/apps/domain/page.dart +++ b/lib/apps/domain/page.dart @@ -0,0 +1,284 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:esse/utils/adaptive.dart'; +import 'package:esse/utils/pick_image.dart'; +import 'package:esse/utils/pick_file.dart'; +import 'package:esse/l10n/localizations.dart'; +import 'package:esse/widgets/emoji.dart'; +import 'package:esse/widgets/button_text.dart'; +import 'package:esse/widgets/input_text.dart'; +import 'package:esse/widgets/shadow_dialog.dart'; +import 'package:esse/widgets/audio_recorder.dart'; +import 'package:esse/widgets/show_contact.dart'; +import 'package:esse/global.dart'; +import 'package:esse/options.dart'; + +//import 'package:esse/apps/assistant/models.dart'; +//import 'package:esse/apps/assistant/provider.dart'; + +class DomainDetail extends StatefulWidget { + const DomainDetail({Key? key}) : super(key: key); + + @override + _DomainDetailState createState() => _DomainDetailState(); +} + +class _DomainDetailState extends State { + bool _showProviders = false; + bool _listHome = true; + + @override + Widget build(BuildContext context) { + final color = Theme.of(context).colorScheme; + final lang = AppLocalizations.of(context); + + return Scaffold( + appBar: AppBar( + title: Text(lang.domain + ' (${lang.wip})'), + bottom: PreferredSize( + child: Container(color: const Color(0x40ADB0BB), height: 1.0), + preferredSize: Size.fromHeight(1.0) + ), + actions: [ + TextButton( + onPressed: () { + this._listHome = true; + this._showProviders = !this._showProviders; + setState(() {}); + }, + child: Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Text(this._showProviders ? lang.domainShowName : lang.domainShowProvider) + ) + ), + ] + ), + body: Container( + padding: const EdgeInsets.all(10.0), + alignment: Alignment.topCenter, + child: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: this._listHome + ? (this._showProviders ? _ListProviderScreen() : _ListNameScreen()) + : (this._showProviders ? _AddProviderScreen() : _RegisterScreen()), + ))), + floatingActionButton: FloatingActionButton( + onPressed: () => setState(() { + this._listHome = !this._listHome; + } + ), + child: Icon(this._listHome ? Icons.add : Icons.arrow_back, color: Colors.white), + backgroundColor: Color(0xFF6174FF), + ), + ); + } +} + +class _ListNameScreen extends StatelessWidget { + const _ListNameScreen({Key? key}) : super(key: key); + + Widget _nameItem(int id, String name, String provider, bool isActive, ColorScheme color) { + return Card( + elevation: 0.0, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 8.0), + child: Container( + decoration: BoxDecoration(color: color.surface, borderRadius: BorderRadius.circular(15.0)), + child: ListTile( + contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0), + leading: Container( + padding: EdgeInsets.only(right: 12.0), + decoration: new BoxDecoration( + border: new Border(right: new BorderSide(width: 1.0, color: Color(0xA0ADB0BB)))), + child: isActive ? Icon(Icons.toggle_on, color: color.primary) : Icon(Icons.toggle_off), + ), + title: Text(name, style: TextStyle(fontWeight: FontWeight.bold)), + subtitle: Row( + children: [ + Expanded(child: Text(provider)), + ], + ), + trailing: Icon(Icons.keyboard_arrow_right, size: 30.0), + ) + ), + ); + } + + @override + Widget build(BuildContext context) { + final color = Theme.of(context).colorScheme; + + return Column( + children: [ + _nameItem(0, "Sun", "domain.esse", true, color), + _nameItem(0, "Huachuang", "domain.esse", false, color), + _nameItem(0, "sun", "eth.esse", true, color), + ] + ); + } +} + +class _ListProviderScreen extends StatelessWidget { + const _ListProviderScreen({Key? key}) : super(key: key); + + Widget _providerItem(int id, String name, String address, bool isDefault, ColorScheme color, AppLocalizations lang) { + return Card( + elevation: 0.0, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), + margin: new EdgeInsets.symmetric(horizontal: 10.0, vertical: 8.0), + child: Container( + decoration: BoxDecoration(color: color.surface, borderRadius: BorderRadius.circular(15.0)), + child: ListTile( + contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0), + leading: Container( + padding: EdgeInsets.only(right: 12.0), + decoration: new BoxDecoration( + border: new Border( + right: new BorderSide(width: 1.0, color: Color(0xA0ADB0BB)))), + child: Icon(Icons.sync), + ), + title: Text(name, style: TextStyle(fontWeight: FontWeight.bold)), + subtitle: Row( + children: [ + Expanded(child: Text(address)), + ], + ), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (isDefault) Text(lang.default0, style: TextStyle(color: color.primary)), + Icon(Icons.keyboard_arrow_right, size: 30.0), + ] + ) + ) + ), + ); + } + + @override + Widget build(BuildContext context) { + final color = Theme.of(context).colorScheme; + final lang = AppLocalizations.of(context); + + return Column( + children: [ + _providerItem(0, "domain.esse", "0x89d240...77407b0e", true, color, lang), + _providerItem(0, "eth.esse", "0x89d240...77407b0e", false, color, lang), + ] + ); + } +} + +class _RegisterScreen extends StatefulWidget { + const _RegisterScreen({Key? key}) : super(key: key); + + @override + _RegisterScreenState createState() => _RegisterScreenState(); +} + +class _RegisterScreenState extends State<_RegisterScreen> { + bool _showProviders = false; + List _providers = ['']; + int _providerSelected = 0; + + TextEditingController _nameController = TextEditingController(); + TextEditingController _bioController = TextEditingController(); + + FocusNode _nameFocus = FocusNode(); + FocusNode _bioFocus = FocusNode(); + + @override + Widget build(BuildContext context) { + final color = Theme.of(context).colorScheme; + final lang = AppLocalizations.of(context); + + this._providers = ["domain.esse", "eth.esse", "btc.esse"]; + final maxIndex = this._providers.length - 1; + + return Column( + children: [ + Container( + padding: EdgeInsets.symmetric(vertical: 10.0), + height: 60.0, + width: 600.0, + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + TextButton(child: Icon(Icons.navigate_before), + onPressed: this._providerSelected > 0 ? () => setState(() { + this._providerSelected = this._providerSelected - 1; + }) : null, + ), + Expanded( + child: Center( + child: Text( + this._providers[this._providerSelected], + style: TextStyle(fontWeight: FontWeight.bold)), + )), + TextButton(child: Icon(Icons.navigate_next), + onPressed: this._providerSelected < maxIndex ? () => setState(() { + this._providerSelected = this._providerSelected + 1; + }) : null, + ), + ] + )), + Container( + padding: EdgeInsets.symmetric(vertical: 10.0), + child: InputText( + icon: Icons.account_box, + text: lang.domainName, + controller: _nameController, + focus: _nameFocus), + ), + Container( + padding: EdgeInsets.symmetric(vertical: 10.0), + child: InputText( + icon: Icons.campaign, + text: lang.bio, + controller: _bioController, + focus: _bioFocus), + ), + const SizedBox(height: 20.0), + ButtonText(action: () {}, text: lang.send), + ] + ); + } +} + +class _AddProviderScreen extends StatefulWidget { + const _AddProviderScreen({Key? key}) : super(key: key); + + @override + _AddProviderScreenState createState() => _AddProviderScreenState(); +} + +class _AddProviderScreenState extends State<_AddProviderScreen> { + TextEditingController _addrController = TextEditingController(); + FocusNode _addrFocus = FocusNode(); + + @override + Widget build(BuildContext context) { + final color = Theme.of(context).colorScheme; + final lang = AppLocalizations.of(context); + + return Column( + children: [ + Container( + padding: EdgeInsets.symmetric(vertical: 10.0), + child: Text(lang.domainAddProvider, style: TextStyle(fontWeight: FontWeight.bold)), + ), + Container( + padding: EdgeInsets.symmetric(vertical: 30.0), + child: InputText( + icon: Icons.location_on, + text: lang.address, + controller: _addrController, + focus: _addrFocus), + ), + ButtonText(action: () {}, text: lang.send), + ] + ); + } +} diff --git a/lib/apps/group_chat/add.dart b/lib/apps/group_chat/add.dart index 6e723e6..25ddc02 100644 --- a/lib/apps/group_chat/add.dart +++ b/lib/apps/group_chat/add.dart @@ -231,7 +231,9 @@ class _GroupAddPageState extends State { onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => QRScan(callback: _scanCallback)) ), - child: Text(lang.scanQr, style: TextStyle(fontSize: 16.0)), + child: Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Text(lang.scanQr, style: TextStyle(fontSize: 16.0))), ), ], bottom: TabBar( @@ -278,7 +280,7 @@ class _GroupAddPageState extends State { controller: _joinAddrController, focus: _joinAddrFocus), const SizedBox(height: 20.0), - ButtonText(action: _join, text: lang.send, width: 600.0), + ButtonText(action: _join, text: lang.send), const SizedBox(height: 20.0), const Divider(height: 1.0, color: Color(0x40ADB0BB)), const SizedBox(height: 10.0), @@ -517,7 +519,7 @@ class _GroupAddPageState extends State { ), ), const SizedBox(height: 20.0), - ButtonText(action: _create, text: lang.create, width: 600.0), + ButtonText(action: _create, text: lang.create), const SizedBox(height: 20.0), const Divider(height: 1.0, color: Color(0x40ADB0BB)), const SizedBox(height: 10.0), diff --git a/lib/apps/service/list.dart b/lib/apps/service/list.dart index 95457a9..da4a6c2 100644 --- a/lib/apps/service/list.dart +++ b/lib/apps/service/list.dart @@ -12,6 +12,7 @@ const List INNER_SERVICES = [ InnerService.Files, InnerService.Assistant, InnerService.GroupChat, + InnerService.Domain, ]; class ServiceList extends StatefulWidget { diff --git a/lib/apps/service/models.dart b/lib/apps/service/models.dart index a7cb844..a735eff 100644 --- a/lib/apps/service/models.dart +++ b/lib/apps/service/models.dart @@ -4,11 +4,13 @@ import 'package:esse/l10n/localizations.dart'; import 'package:esse/apps/assistant/page.dart'; import 'package:esse/apps/file/list.dart'; import 'package:esse/apps/group_chat/list.dart'; +import 'package:esse/apps/domain/page.dart'; enum InnerService { Files, Assistant, GroupChat, + Domain, } extension InnerServiceExtension on InnerService { @@ -20,6 +22,8 @@ extension InnerServiceExtension on InnerService { return [lang.assistant, lang.assistantBio, 'assets/logo/logo_assistant.png']; case InnerService.GroupChat: return [lang.groupChat, lang.groupChatIntro, 'assets/logo/logo_group_chat.png']; + case InnerService.Domain: + return [lang.domain, lang.domainIntro, 'assets/logo/logo_domain.png']; } } @@ -31,6 +35,8 @@ extension InnerServiceExtension on InnerService { return AssistantDetail(); case InnerService.GroupChat: return GroupChatList(); + case InnerService.Domain: + return DomainDetail(); } } } diff --git a/lib/l10n/localizations.dart b/lib/l10n/localizations.dart index 338bcc3..565bd18 100644 --- a/lib/l10n/localizations.dart +++ b/lib/l10n/localizations.dart @@ -57,6 +57,7 @@ abstract class AppLocalizations { String get onlineSuspend; String get onlineLost; String get nickname; + String get bio; String get id; String get address; String get remark; @@ -90,6 +91,7 @@ abstract class AppLocalizations { String get invite; String get emoji; String get record; + String get default0; String get others; String get closed; @@ -171,8 +173,10 @@ abstract class AppLocalizations { // services String get files; String get filesBio; + String get assistant; String get assistantBio; + String get groupChat; String get groupChats; String get groupChatAdd; @@ -198,6 +202,14 @@ abstract class AppLocalizations { String get groupCheckTypeDeny; String get members; String get groupRequireConsent; + + String get domain; + String get domainIntro; + String get domainShowProvider; + String get domainShowName; + String get domainName; + String get domainProviderAdress; + String get domainAddProvider; } class _AppLocalizationsDelegate diff --git a/lib/l10n/localizations_en.dart b/lib/l10n/localizations_en.dart index aecfb61..6a9b0c0 100644 --- a/lib/l10n/localizations_en.dart +++ b/lib/l10n/localizations_en.dart @@ -39,6 +39,8 @@ class AppLocalizationsEn extends AppLocalizations { @override String get nickname => 'Name'; @override + String get bio => 'Bio'; + @override String get id => 'ID'; @override String get address => 'Address'; @@ -105,6 +107,8 @@ class AppLocalizationsEn extends AppLocalizations { @override String get record => 'Record'; @override + String get default0 => 'Default'; + @override String get others => 'Others'; @override String get closed => 'Closed'; @@ -306,4 +310,18 @@ class AppLocalizationsEn extends AppLocalizations { String get members => 'Members'; @override String get groupRequireConsent => "Requires manager's consent"; + @override + String get domain => 'Domain'; + @override + String get domainIntro => 'Unique identity to global'; + @override + String get domainShowProvider => 'show all providers'; + @override + String get domainShowName => 'show all names'; + @override + String get domainName => 'Username'; + @override + String get domainProviderAdress => 'Provider Network Address'; + @override + String get domainAddProvider => 'Add new provider'; } diff --git a/lib/l10n/localizations_zh.dart b/lib/l10n/localizations_zh.dart index 2d56878..7c59376 100644 --- a/lib/l10n/localizations_zh.dart +++ b/lib/l10n/localizations_zh.dart @@ -39,6 +39,8 @@ class AppLocalizationsZh extends AppLocalizations { @override String get nickname => '昵称'; @override + String get bio => '个性签名'; + @override String get id => '身份账户'; @override String get address => '网络地址'; @@ -105,6 +107,8 @@ class AppLocalizationsZh extends AppLocalizations { @override String get record => '语音'; @override + String get default0 => '默认'; + @override String get others => '其他'; @override String get closed => '已关闭'; @@ -306,4 +310,18 @@ class AppLocalizationsZh extends AppLocalizations { String get members => '成员'; @override String get groupRequireConsent => "需要管理员同意"; + @override + String get domain => '分布式域名'; + @override + String get domainIntro => '管理自己的公开身份'; + @override + String get domainShowProvider => '展示所有服务商'; + @override + String get domainShowName => '展示所有注册名'; + @override + String get domainName => '用户名'; + @override + String get domainProviderAdress => '服务商网络地址'; + @override + String get domainAddProvider => '添加新的服务商'; } diff --git a/lib/pages/account_generate.dart b/lib/pages/account_generate.dart index 42c108b..2adfdf7 100644 --- a/lib/pages/account_generate.dart +++ b/lib/pages/account_generate.dart @@ -214,6 +214,7 @@ class _AccountGeneratePageState extends State { ), const SizedBox(height: 32.0), ButtonText( + width: 450, text: lang.next, enable: _mnemonicChecked, action: () { @@ -270,7 +271,7 @@ class _AccountGeneratePageState extends State { }), ), const SizedBox(height: 32.0), - ButtonText(text: lang.ok, action: () => registerNewAction(lang.setPin), + ButtonText(width: 450, text: lang.ok, action: () => registerNewAction(lang.setPin), enable: this._registerChecked), _footer(lang.hasAccount, () => Navigator.of(context).pop()), ]) diff --git a/lib/pages/account_restore.dart b/lib/pages/account_restore.dart index 4713180..5aad393 100644 --- a/lib/pages/account_restore.dart +++ b/lib/pages/account_restore.dart @@ -274,6 +274,7 @@ class _AccountRestorePageState extends State { ])), const SizedBox(height: 32.0), ButtonText( + width: 450, text: lang.next, enable: _statusChecked, action: () => _mnemonicRegister(lang.unknown, lang.setPin), diff --git a/lib/widgets/button_text.dart b/lib/widgets/button_text.dart index fdb0482..2a12de4 100644 --- a/lib/widgets/button_text.dart +++ b/lib/widgets/button_text.dart @@ -12,7 +12,7 @@ class ButtonText extends StatelessWidget { Key? key, required this.action, this.text = '', - this.width = 450.0, + this.width = 600.0, this.height = 50.0, this.enable = true, }) : super(key: key); diff --git a/pubspec.yaml b/pubspec.yaml index 48c6ea4..5dcc726 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -74,6 +74,7 @@ flutter: - assets/logo/logo_assistant.png - assets/logo/logo_files.png - assets/logo/logo_group_chat.png + - assets/logo/logo_domain.png - assets/images/background_light.jpg - assets/images/background_dark.jpg - assets/images/image_missing.png diff --git a/src/apps/domain/mod.rs b/src/apps/domain/mod.rs index 6968310..6bc0334 100644 --- a/src/apps/domain/mod.rs +++ b/src/apps/domain/mod.rs @@ -1,6 +1,8 @@ +use std::sync::Arc; use tdn::types::{ - primitive::HandleResult, - rpc::{json, RpcHandler}, + group::GroupId, + primitive::{HandleResult, PeerAddr}, + rpc::{json, rpc_response, RpcError, RpcHandler, RpcParam}, }; use crate::rpc::RpcState; @@ -9,4 +11,40 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { handler.add_method("domain-echo", |_, params, _| async move { Ok(HandleResult::rpc(json!(params))) }); + + handler.add_method( + "domain-add", + |_gid: GroupId, params: Vec, _state: Arc| async move { + let _provider = PeerAddr::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?; + let _name = params[2].as_str().ok_or(RpcError::ParseError)?.to_string(); + + Ok(HandleResult::rpc(json!(params))) + }, + ); + + handler.add_method( + "domain-remove", + |_gid: GroupId, params: Vec, _state: Arc| async move { + let _id = params[0].as_i64().ok_or(RpcError::ParseError)?; + + Ok(HandleResult::rpc(json!(params))) + }, + ); + + handler.add_method( + "domain-register", + |gid: GroupId, params: Vec, state: Arc| async move { + let _provider = PeerAddr::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?; + let _symbol = params[2].as_str().ok_or(RpcError::ParseError)?.to_string(); + let _bio = params[3].as_str().ok_or(RpcError::ParseError)?.to_string(); + + let _me = state.group.read().await.clone_user(&gid)?; + + // Send to remote domain service. + + // + + Ok(HandleResult::rpc(json!(params))) + }, + ); }