From 89bcfecfb5864fbf72ebc9ade5ead3ef0359c9cd Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Fri, 8 Jul 2022 14:33:57 +0600 Subject: [PATCH] Login guide added --- assets/success.png | Bin 0 -> 21808 bytes lib/components/Login/Login.dart | 69 +++++++++ lib/components/Login/LoginForm.dart | 74 ++++++++++ lib/components/Login/LoginTutorial.dart | 180 ++++++++++++++++++++++++ lib/components/Settings/Login.dart | 108 -------------- lib/components/Shared/Hyperlink.dart | 3 +- lib/models/GoRouteDeclarations.dart | 11 +- pubspec.lock | 23 +-- pubspec.yaml | 1 + 9 files changed, 350 insertions(+), 119 deletions(-) create mode 100644 assets/success.png create mode 100644 lib/components/Login/Login.dart create mode 100644 lib/components/Login/LoginForm.dart create mode 100644 lib/components/Login/LoginTutorial.dart delete mode 100644 lib/components/Settings/Login.dart diff --git a/assets/success.png b/assets/success.png new file mode 100644 index 0000000000000000000000000000000000000000..65cdba354ea0c44b7de09adc3a351ae25e625845 GIT binary patch literal 21808 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 ~=H%x_j5CV5K-wPS4S#QBid ztdGsDxBNe++qmyhbj}TK7FO@A=rQf>vAcL#G$!R#EmZO7?KE0Q?A8=lZ!9=RMuuA$ePGhOz2I4C@f3%c=me2NUtPT$_nE>8{_BhQM(v+5lp`EdqAnZOy{ zj5Vs03Sz7m85L-E5|2a&hlH%Xo*cWRmX80krS+OAWK|b@|N!C1I9q}AR z?>na#U3V5pnLCRcL+~;!sARBd*TYeNaAbCNCgya{jST0*_d1coc zg>9eWH+^ngs?AMLzTW$_cH8V42;iuVIEe-{YbZnA$RX<(3X99k%$bfqMa>_lBy;bj zpWke-JXqy^E6pxcy1rics>pUnTI+tcnqi*CI)!x3Q@TEqA#bpoRNdV2%}Z#u*|O26 zO*gO49w+GwjgW2~TXtL5#wn&^I?N+o`ky(MC$yNbv$1U@)EeA6xRD;pa@^5CiEjp1 z1gBq7NTsxK7Nn342?|;f4McoBRI@9O5>o11HOK>s(oueX>0Z>Bqliw%1J}@NSsmtq zfq`kxqMy#uu^)c29foyPE$`3iFdwroHN&Po?x(-4(+L{Q7S5ZPIg`(2tf{7Y6X3~> ztoN19ec0(#Oh)H)m2eU|wS8vBvf7M{jI2`k^s80;{_YsPy@W8;zWhnerigf2FiuH{ zu(atZ5T}$*$joF5N6Fk9B}R%#t9F3dH;)C>8>C|LT&SH>+9ugd3%WnJFg02hYIR%w zTD!n}E$+>mNhh>@KP^ewZS?U6Ssk2Ir~Gp^mjaXpk)>QQitblAoOI^of}Mm&n&*!k9Y4t- zktoWz>?8Z-@WIRnoLE-hy5S2BY;5f8R`F2(&H=Z0=FA!YtGtqLVq&Ib(BsQ)ZA|xF zWnrlu=CNrP0_!~`Y{a}%GXE@%2sWS)&H46COAbPto&&BQD%7%W#woQC$!olEMjxH; zgh(@=e256gBL*`%%-0xGUB%{#=o$woPx*?(`w-mFX_ySPEX0=fa}OwMjg-zl;4~g7 ze#+IH@qja_)gpF0-QWELAEsTMU+JM??F(PkEs?xY(b%+Z?}*=vLM~?sAk-2EFCS)oigtNkKueKI!qpr`Xam=Cvbk zbJOh}8UI$@(9lp>C)+-}+mywHe92eKQq6b(HRT1RQYx7#?`t<|+;BLiPg>bAF_#|B zQE1)ej*i|*b$RGlZW_iAddgSILQ=3Bg&x@4CY4Dtu=Ul-j%uBVW^!<($jwE*e0v2U zp4(wA!+g$zW`b<#Tbyi4Te-L^JOB+_xuA$hSxJeRFk-&UA$qdlG&6{gPCaiDDRb|X z?_rv@VS5~I!YLntZ}WDU{heN&cq2wpCA0(j^v>{JaD8{z%+phhHaJJ90>}F6Zf<8m zx8?kv+Dw8XTOB<^2{m%c%3s=`|NX^Fm!?)b<1;h&-kg4zt>&?Nqu}Gmvm4}}2tR(@ z6{6SG(6|d;-WWrf1q!jI{Dqo161_P!@4RswIi(LK5}?Q!nBH4h}w3W-n$qW5qP zzzbHM4Q)iB=yP;)w};T9ZIIkqyVW7&QMq4D3KDjzUP@hIukHutnnqo2x?T!v@g^~G z4yAbPAuA=|q?te*qZeB{6$+c*{ec)|_zsAt3qtqr-^Z~=MMZ(>F+bWVW~PJ6{0a_Cd3fGpUX4vJI+-IzkuAFUf)4Zw zK(YO)OI324S!e<0tCG*q88N)0_mX?KO;l=u6w_XOzSuXNHRL6#uZYZ7szLf_TK`cs z5*}H`jJq5ghP-E7$&gd1gx2262%T3EpZb>~crbiVo_X>v$!9zWNM|3uj%oMknRT8J zO?!>ymPYra=H}YCyK50Xjj50#FY!mB>wQI;0uar7%__Ah9L^>>oE4!H7%`*EK@}jI zBDbfD#XiMwPP9ek2rmpU65*_%!m)45d}82#e_uI8D*=ZVY+@w9$xiqofGV-sc3&SsAu zJ<`|z{PXBxO#2|TS4@WHs`H*Bt-OPF4@!HSmNRMlyw_JAul&9DCgUsZBgiSk*fd^z z8l7LR6G_*rh?O@FIAzf849L=#{{H@oY=&+z#+dfpuVZ`+-3S!6M8IG7GD5t;($`kC z9fsj%Iv7JiJM>c^D=HE#v$B1%`U=9Uy!8xnN((nSe4LcjFz-#?to}OiH~=VcAx$Tn zJ`bkdP_dlN+sm-9FllD}c{BotYyD|{vn@&8Cx1Fr@CmF2oobNDfv0VxH0I z)by)JhftnpFa8cm7*;nQOnt2}?y(>@RZRr_#fuu++K!JBj4m;HYUPb4ysehgI2DL$SDNGX(m2RC=|^p zdGyP=VMg(@rN=Str2IKI= zR_%D9l95@~FjBkfE)I>q?p7HOzILx)s*-|xxTp&jruXk5V(g8Kr0-ERmoxOh{(b__ zw2QnU!R!c~CP8F(XD0+e&_jZ?c#R!U&F$PR z%L>lSWRT$RGcP=<8)uY?f=Fb`?K^C=vV=VT^XJd?^)gC?DD9UKD;#+zJ1o+oK2w%_ z29v1t3?F`o!wJIHT1akcM><}aPlE>7ns46}1>&6QDrZ!~u#96P4|{q40J>dFnVrx7bJGcu5%BpNO$F0h;6O1%@T z3_sdltL`vA>G>JUD*Uk#xdR&a^4+^D7<;SC%<<*TJ-t2r|JIXq;}c0$>9-vZt$HuL?1&U0AMK zR_P!2Q9gm{&t>wc{YGg3gX=f*LDnh@iy^(!Uyb-;)1Vt}?Ftlo3H-%6L1Nk&4=BB= zYG&d3xR@A#otFo)J5MEZZWk#HHjkTJK4vY4F6(b>cCa_9Mvb!I;?L6 zMMW6Wdc5!GA59d+6@-Uhgk!a(z|}356Alo2Ocor^kwuqjy}LV^_7{crFAyFsSExIz z86}e>WD79eVWi215PioHkoK4%r_Y2%r}L%~1js+v`Hz%EKned<^Ng*d4aXbyE?o(5NfGMSqILyio( z3|u(Q$j?=c@}(Jnk+Yolke4VHPvw^-2Wy3-f%UP8iAnvkFeEjgll0J@r)ag6J}p9a zA^S==UQtDbX)iG(B;@B<}bds7Z2;y`ZosgPy zn^WZjPDlvM_-V=g;GBlKr!fTMd3kxzi7#`HUiWy@lCw`L29NKYx)P9lvALOP)8(1| zqeqwN$>mbo9&oC1MwVD!qK6rRgM-7cRbL9Q;*t1K3GcS*?4Gb_y{$-turt2pnEh~W z2H--7p4?X|tKkcr3pjV)PmjuR={6oBoR;da3xOeN5a=_dI+tfZ))I&dZXAJFr>?F} zZtoFfu-{u-(=kXTLYe6NkU0*gFjeL~+WG0&?KjRN!Z@Q`;{spe##*bIaOch)xuR!wZM;dXxx4YGQf=q)WmWFp1#X%^8B^Wt;tx760Q!?! zoAbp)MLkB1n*oIZBxUY#Mxxhk&T9KcIA&lnetOAav2)UBkvrH?IbuFB(PM9C!%zk9 zkGn%utp>LgkgTYrbmsJF`n^a<3Lpo8Y*8Rie1|qtK`r8wU7%!Q+|1GfEzL*xJp`&Z zuZH7|qB}!}!9*1h;V6g?pxHG%XF5jF#M|4uzUAw?ckdun)r=~4BjJuwT-yqV{3N(_ zVyf(Wymfh1xmLDXo<@YR+rBy!&Vp+-MSk*F zqxstcIcg0fix&urb;BPsGx<~1Ut_I*S{GZzIMfyF3sLH_PA6e%CE(a$I2i=K?IG<) zwXD@GL+~Q*i(eUZ$q2jd?pRnF{HbgG2J3<}piGJzQ0QK%c2VkI7`Y-{s1;mq(3~Z? zwz}$DrwM`XiYtlMw63oRYXS;^9zpSM?6Q*(l{CR9E&O{p!AP$OxTZWx9E`my6-#8o5?c1eg9r& zt|UQP6s+G9T&#vHmZ{WDiizR?rJ! zBrXBv)0SvjkLwUMUb=}dL_uX`4wLb~az;L_zvMjfWH~?WnUT;|GyXs0DSy7PH?K9{ zBmeMWPB=#iRkyQKu~;{OJ!yIfq^}^7z=rS&jd-CGajcfSA|gG5gFHqmRs~ctc1tY3#>U>GQ-6i2( z3IIB+)Pc||1t)+S==#Ka#_DxTwUwJpm7>NB@=C0&inX$(-qm={DvvI2B07PvfdhFX zBO}Rr@^=BnDE+17@s}@y2tLJWaEQRTK~@s7va(`%`A=;C`pyAOaBy{seW}>>>qC37RJ(c4 ziJk0%BKEenuOIe;ocayS%>yD%p8#Elh@hcPAI?AuSWC^WrXtS8%OGG^zI_YI3w^(x zG`_-wX>WC~c2#RnfGx<;=B9Hg1MuoE6?^@D^~un7BV^!`$7!=PB(Ww z`7dU+rR0W<#nAzUXk9LbXSHUs?bSnqrPBrjhOVx!w|@Ip;)6U=&5Y2w65R~N$J^*+ z7b+QEYiA&P!A-3zVu2@4mUNqp@)*zmq;*Z^9%QG%ek`i07j^><2S+#pp(>9bx{PSM z4+7O-Z7LayR%Fw$_rlyWx*H>Zq`VH;mAGd3gb9a_c2=fGVjU1k}%;N4z)! zG?Wm%K$QkS8Y_x&FR;0aFOki2eO4=*I6<3Vgf!p+3K$@zJJ`oykkULkoDw2{AD{CORD zaHAS$WLkQ9bhW9hoE!p`*Q^izBGXp_-3VAYbX>(_|m<&>HAjP%r)Wx%!5)JEDVv_U@+!c3r|=!_`olaX)Kag4}Li_2bMa_S(cMd zfOz6QEzOIxv@|Li;4Zl}<1wA9vMKknI)Z*dq}?E+#3Fb>=44O51Iu~B)F(Slh=6HR zHL^O6>S}ANm-lm12LjtypTrBC0N6o{;>%|%&{+KuvitIXL9P$gxvI@AC@EQOz@*M{ z6@db?$vG2YT$V$pE|}#9fiY|w7jikg`s17A4^Kf%>17)^BL4fnkoRJ1>!IH1B&+z$*=;LRQCv5I>w?o^!^8S* z!!IJ?pqP3p256l&vz3R2jj<#oRA2Ys3$PH`O2N|%UOI&f3~Bl5xmsSR#K8HYaJ(76 zh_JBRXwoI%WDN`q^!2YKD2o;dkw{-b9HV1kKp>vKjCdgl95OJQifj|(<6txDUNatM zW@h&G_HcQOB4jte+f%@6KrM(Z95fB;ZB4fPLBYY0iDYDEKGrJlr{2vRK8wLXF|&gZ zGJ3#aEu^Ytr9RdId#N{o2ZBf-tHGFqik5*PAt3=GJy7?gR`slo%VMIF7Y<@}y7`fr znVF4^jR1eXEQx`;oRJkmOecyiBV=F?aYn#Yop=R$$3gW#_2%5u91T%h89gYoNHd4| z`W_p(f#IS?eH(x*2$Ml|%J%^$0)+uHm1edWM9=~GD9zkv#vh{?g+@fpeCESoSY__X z<4Kqi=N7I;cU!7O8MEm9nrt3Z&;w=!)(dBz7hSbgJG8l>c9Ge^8U6X!4@&`XQ@|*V z*~8))Lt7#EsC50*OK1l70OkQ_+Noq9%8O02d!Kh4qydQ+u&nZ^A=_-VEFhKkE2BtM zI|Ly2#N^6z%YNIBFDxuPBdndNY#LuwQjb}mH}&TEg4j{~&~*4#MaFD(@{_VWtZ zS#|*rJMKrFmqfdFR}i!(K5^2Frr_ z0Pq5wH#RoP$;$q!jBv%lByDYNwnAbsx1=Nw3fmT_ZTte#b$v%2Nzc~zjQYHnY2Ymp z4?zdrE3LJY6w(O+$zKfepb9dw)%WGgm&wV=A3t7qPdW;ZNX>M0b$$8r!tUCylGR)e zv`7Ls)u{uPYEb)??=~F3h(IGqs~jN|f+771d#y&gZz~ak7^s3P&#P;nh)+t|k7&_9 zOX$tC&x!Rxg{8(K`_21-&d%cBKKh{a^+a|E=Nszpr5xKA%fti?HMLr$w7E9@YIlPB z#z`bnkuQc7@!TJp1)vOp{I;_rhP* zB%aSBs8Y1KMSq0h_Bmb>lEKS}`n#%;5vRE@ltT9IHyy$gewr6L>evXxt-4pLWnCiE zjXD6ntPUYbeK@)!%TJ3y90`m#O5O>(Bguee#pi$EK=Z}$tJMK209mMUqXL+&zEd(gohZz)uTT z+@sQrLZC!?io=0Q4?9sHkK)~@-0?Nch^H5z-WV!jy>#U(5u@6{@qh&rZM+wqH}ZS< zlulDF)G4kJCxX7;;Hti!vKcgUuON{dfc>a$?+T840hO|_^Qcnxc=`bS_fObw$1RnQx+u#EY zBmk%Pz#&HH*4dbwyjd0ahz!&I7+_pE&4`2Q_jH#P&|@PL3`4wSIqc#17t_Xkmy`&Q z#c#hhDad%NC6b_AqRSVvGM#v9zxDIeeo}QGUV7nUXLoN!omzKaHDLS!f*F6`PXD`1 z^GaRGp1|DBX=`Quw4NGS94=|1?;_ZjjE}|eO%2kElXnZXoF+QuL=tq@vAS6u_OoO7 zo6Hxl2Szx;i6@5=7I?h_SfMmrZUe+$0XxHx71VL8%7^y3%j{vGC2K9hJIo8$=jjf= zfSV+e=2`b30IVBc035EZl@enVtdbpB+^DUsh5CUIJtHkGpK5q=b;*JtWPjb^hy_d=~}!?ak|ycG&dIkX7mu-WH44;&6NZLsrF@Y!J5#)bwFMZBdz@Af>$2bHKX zn0y9Bx^Wu_9F&p?-=zYc0Yq^r0@co+EjUlHA9_A0@0aK)zycamk2gZf1w2?z9JVZ{ zfFXwN`tb3OiUfYapE%zv_c43n;ltXY(xI=hzdIvO`%2xoaiib!Hn3;Ff}}W&c6Ghs zP54n|!>aN5>*x~-lVQl~>N6(AnEZifJO*iXGleKQIeAaMh6+C|15`h5A^^y=SEKE& zLtEQ0&50+yjN+d@QX6J){N35Iq^}UQdgZy=BN7W;{ErKER8*f-ces@qb!oFF8TP;)(D;Rh7W>;zJ-c= zwj2Sq>cWqBpvi0Y!{j@=V@nC3qQY~Ewzw1s!_EZ057YbkS1P7&sVI=E8Jap?9i=A#DOA-xJC68zKjQ&V ze`AZs)tC{-Y==zbxT9}4=@mjeWPVd=zque+FOJxh4^PAyd8$?Va57b(OyeG_nrdNP zy9HQK2Ir9My@D0^4{fLUb?pU{FnppQN>g$NkNYnpi$W6Ir(b$L<6HS)=BR|RxGi1>4t?3GE!!bCmF9j#lfA)lv!wSUW z&qQBFB#d`mqpg1m-zPL+p@7l0sSt@|bx1Q^dCP*s5r8X|+<(IW z1QsBMWw+r@WU!U`)kw78!zmJ=l|+K;pX|W!JCH7dnl=`_=Uw6r$Af!RTYKsPvqSDn zguY86wB3OLMK?oM0`;}6ve(AKk!Yx`+m|Xz)H15GuYrR6*6GLS9F6L3ujCe>OEt*tsaRtjh=_*Tb|2r5*k6CG15#H?jGE}K|+6!ZZ- z`5uOSHdSWbT!??b*|E<8M^RKUOu##=2JWB(I?W3K!^d7lutJ8`TWES!9f5+kT!{cv zDO0FbXj>o}qv(7?Z(AM*uaY3SH6f33Y2&{ZiFUF_@I|6Eb^Scg{O=n9xQJ0H5zidtlNY25>VwwMr~s)v{q8nyfNp0sSB4Q_Cz$?^pD{ zbRuai9&i)@OG_WYa=0fSo!&|LYd36mI;NWnO?oFb~Bisfs(jO5y-mrkf z!GmQ(OD7t6IbI-SJkq^lUmu^CW_+Q+#@J*72ZS%N=m(cU=r%+&<`-KiXF)Z_mS3}p z!-o!GwEt9O?BUy++!und3OlZ)kZ4)h)H(5dwBL+K&47ZSikA512t*HS^(RB`BA(6_ zs=lD00JBD-wD4v2H2`~rJ2#VMrKMs#Q_g%{hM~d+~*+eP$+ol(xsVlbqWoj z8l6oIf>|_=^=@hT-OGXvp*k4b%n8E-2;FEpKCqt&ZFuOg#Po>~&K@+<9^!%_o?Am< zh%?L8?ASXcDkKD;PbFhk0lk=pcd-cjRr)K#aa6>&s|%Q;eI)lwEE|`En|f$;`=c&< z%_T$AeNJB=quFh$QV~yQ+-y=Q2OY36eq?9WeCDCvQsf9`7w%-*|;kGtS-h4o*^!EF7xdiV+?7b4G*VG7&?ksm_+)s z7PMKZXffxB?1vAS707Q+%q(U|P0Z{~<*Nyq{nr5Bbi^!eumxe`L1sm`xJ>7;#1O7V z1frBnC!U3wsC}YYFsI4bYCJMI<{o=N4U+bJFblk~#%AH@%Af_$E@6Nse|V#wGujga ziN~5y=o~3K2*OxV58%rgI>6mjQ_u8MQ0hi{g8l0wSYcp!M z4ulewY)Q&oSCBF1{pY%XfB-xottSD(^^7D1sZPcyC%zhB`Vk}ZC`1g(&%~Cn;I~n( z?Ofiz`?FIPFWK_o1{&bM;jEnsdEkt-??1;IhKvb)dtz5zS2SNCv4c2gipM72g~)vuudnNJL#;V8`F(M7)T=F}>`nZ>TERdXMyR;3j7^XddcHqTe*rN+ zfXxzmyKryeL#4VdIj=9L`v3%DX}VivLbyCJPrTxlVhbEe6-#3%qc=O-&B=rjT{hft zq87VR4T3V?AwNSQrtMf1cF60x8mh7`S5_t`CH4QP1;ZlR!@YiEdUNtm9Rj)6X-{Ns zI1~0eQGF}@C&wWY-0~pu;+x@-s3qnuu*Z~PYSt;WHU-12LSO^F*<$Ipl#gt(5DV_v zsG6+j5#$l3SDqHLDy3dpaMy)P6-evCAcRZt<`W!Gb%%{S+Jp?18^9wGJuR2%9=L#4 zlG)w(fe7hVQDqU<2?D8t{+G6f7olKRTX5*O5)eNSbQ7Hh62~webpJKz?6Rgl4-Zq literal 0 HcmV?d00001 diff --git a/lib/components/Login/Login.dart b/lib/components/Login/Login.dart new file mode 100644 index 00000000..42b82055 --- /dev/null +++ b/lib/components/Login/Login.dart @@ -0,0 +1,69 @@ +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:spotube/components/Login/LoginForm.dart'; +import 'package:spotube/components/Shared/Hyperlink.dart'; +import 'package:spotube/components/Shared/LinkText.dart'; +import 'package:spotube/components/Shared/PageWindowTitleBar.dart'; +import 'package:spotube/hooks/useBreakpoints.dart'; +import 'package:spotube/models/Logger.dart'; + +class Login extends HookConsumerWidget { + Login({Key? key}) : super(key: key); + final log = getLogger(Login); + + @override + Widget build(BuildContext context, ref) { + final breakpoint = useBreakpoints(); + + final textTheme = Theme.of(context).textTheme; + + return Scaffold( + appBar: const PageWindowTitleBar(leading: BackButton()), + body: SingleChildScrollView( + child: Center( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 10), + child: Column( + children: [ + Image.asset( + "assets/spotube-logo.png", + width: MediaQuery.of(context).size.width * + (breakpoint <= Breakpoints.md ? .5 : .3), + ), + Text("Add your spotify credentials to get started", + style: breakpoint <= Breakpoints.md + ? textTheme.headline5 + : textTheme.headline4), + Text( + "Don't worry, any of your credentials won't be collected or shared with anyone", + style: Theme.of(context).textTheme.caption, + ), + const SizedBox(height: 10), + LoginForm( + onDone: () => GoRouter.of(context).pop(), + ), + const SizedBox(height: 10), + Wrap( + alignment: WrapAlignment.center, + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + const Text("Don't know how to do this?"), + TextButton( + child: const Text( + "Follow along the Step by Step guid", + ), + onPressed: () => GoRouter.of(context).push( + "/login-tutorial", + ), + ), + ], + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/components/Login/LoginForm.dart b/lib/components/Login/LoginForm.dart new file mode 100644 index 00000000..3131ec8f --- /dev/null +++ b/lib/components/Login/LoginForm.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:go_router/go_router.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:spotube/helpers/oauth-login.dart'; +import 'package:spotube/models/Logger.dart'; +import 'package:spotube/provider/Auth.dart'; + +class LoginForm extends HookConsumerWidget { + final void Function()? onDone; + LoginForm({this.onDone, Key? key}) : super(key: key); + + final log = getLogger(LoginForm); + + @override + Widget build(BuildContext context, ref) { + Auth authState = ref.watch(authProvider); + final clientIdController = useTextEditingController(); + final clientSecretController = useTextEditingController(); + final fieldError = useState(false); + + Future handleLogin(Auth authState) async { + try { + if (clientIdController.value.text == "" || + clientSecretController.value.text == "") { + fieldError.value = true; + } + await oauthLogin( + ref.read(authProvider), + clientId: clientIdController.value.text, + clientSecret: clientSecretController.value.text, + ).then( + (value) => onDone?.call(), + ); + } catch (e) { + log.e("[Login.handleLogin] $e"); + } + } + + return ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 400, + ), + child: Column( + children: [ + TextField( + controller: clientIdController, + decoration: const InputDecoration( + hintText: "Spotify Client ID", + label: Text("ClientID"), + ), + keyboardType: TextInputType.visiblePassword, + ), + const SizedBox(height: 10), + TextField( + controller: clientSecretController, + decoration: const InputDecoration( + hintText: "Spotify Client Secret", + label: Text("Client Secret"), + ), + keyboardType: TextInputType.visiblePassword, + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () async { + await handleLogin(authState); + }, + child: const Text("Submit"), + ) + ], + ), + ); + } +} diff --git a/lib/components/Login/LoginTutorial.dart b/lib/components/Login/LoginTutorial.dart new file mode 100644 index 00000000..5a4ccc07 --- /dev/null +++ b/lib/components/Login/LoginTutorial.dart @@ -0,0 +1,180 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:go_router/go_router.dart'; +import 'package:introduction_screen/introduction_screen.dart'; +import 'package:spotube/components/Login/LoginForm.dart'; +import 'package:spotube/components/Shared/Hyperlink.dart'; +import 'package:spotube/components/Shared/PageWindowTitleBar.dart'; +import 'package:spotube/provider/Auth.dart'; + +class LoginTutorial extends ConsumerWidget { + const LoginTutorial({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context, ref) { + final auth = ref.watch(authProvider); + + return Scaffold( + appBar: PageWindowTitleBar( + leading: TextButton( + child: const Text("Exit"), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ), + body: IntroductionScreen( + next: const Text("Next"), + back: const Text("Previous"), + showBackButton: true, + overrideDone: TextButton( + child: const Text("Done"), + onPressed: auth.isLoggedIn + ? () { + GoRouter.of(context).go("/"); + } + : null, + ), + pages: [ + PageViewModel( + title: "Step 1", + image: CachedNetworkImage( + imageUrl: + "https://user-images.githubusercontent.com/61944859/111762106-d1d37680-88ca-11eb-9884-ec7a40c0dd27.png"), + bodyWidget: Wrap( + children: [ + Text("First, Go to ", + style: Theme.of(context).textTheme.bodyText1), + Hyperlink( + "developer.spotify.com/dashboard ", + "https://developer.spotify.com/dashboard", + style: Theme.of(context).textTheme.bodyText1!, + ), + Text( + "and Login if you're not logged in", + style: Theme.of(context).textTheme.bodyText1, + ), + ], + ), + ), + PageViewModel( + title: "Step 2", + image: CachedNetworkImage( + imageUrl: + "https://user-images.githubusercontent.com/61944859/111762507-473f4700-88cb-11eb-91f3-d480e9584883.png"), + bodyWidget: Text( + "Now, create an Spotify Developer Application by Clicking on the \"CREATE AN APP\" button. Give it a name and description too", + textAlign: TextAlign.left, + style: Theme.of(context).textTheme.bodyText1, + ), + ), + PageViewModel( + title: "Step 3 [Really Important!]", + bodyWidget: Column( + children: [ + Text( + "Tap on the \"EDIT SETTINGS\" Button & navigate to \"Redirect URIs\" section", + textAlign: TextAlign.left, + style: Theme.of(context).textTheme.bodyText1, + ), + const SizedBox(height: 10), + Wrap( + crossAxisAlignment: WrapCrossAlignment.center, + children: [ + Text( + "Add", + style: Theme.of(context).textTheme.bodyText1, + ), + TextButton( + child: Text( + "http://localhost:4304/auth/spotify/callback", + style: Theme.of(context).textTheme.bodyText1?.copyWith( + color: Theme.of(context).primaryColor, + ), + ), + onPressed: () async { + await Clipboard.setData( + const ClipboardData( + text: "http://localhost:4304/auth/spotify/callback", + ), + ); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + width: 300, + behavior: SnackBarBehavior.floating, + content: Text( + "Copied http://localhost:4304/auth/spotify/callback to clipboard", + textAlign: TextAlign.center, + ), + ), + ); + }, + ), + Text( + "to \"Redirect URIs\"", + style: Theme.of(context).textTheme.bodyText1, + ), + ], + ), + const SizedBox(height: 10), + Wrap( + runSpacing: 10, + spacing: 10, + children: [ + ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 500), + child: CachedNetworkImage( + imageUrl: + "https://user-images.githubusercontent.com/61944859/172991668-fa40f247-1118-4aba-a749-e669b732fa4d.jpg", + ), + ), + ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 700), + child: CachedNetworkImage( + imageUrl: + "https://user-images.githubusercontent.com/61944859/111768971-d308a180-88d2-11eb-9108-3e7444cef049.png", + ), + ), + ], + ), + ], + ), + ), + PageViewModel( + title: "Step 4", + image: CachedNetworkImage( + imageUrl: + "https://user-images.githubusercontent.com/61944859/111769501-7fe31e80-88d3-11eb-8fc1-f3655dbd4711.png"), + body: + "Finally, reveal the \"Client Secret\" by clicking on the \"SHOW CLIENT SECRET\" text\n Copy the Client ID & Client Secret then Paste them in the next Screen", + ), + PageViewModel( + title: "Step 5", + bodyWidget: Column( + children: [ + Text( + "Paste the Copied \"Client ID\" and \"Client Secret\" Here", + style: Theme.of(context).textTheme.bodyText1, + ), + const SizedBox(height: 10), + LoginForm(), + ], + ), + ), + if (auth.isLoggedIn) + PageViewModel( + decoration: const PageDecoration( + bodyAlignment: Alignment.center, + ), + title: "Success🥳", + image: Image.asset("assets/success.png"), + body: + "Now you're successfully Logged In with your Spotify account. Good Job, mate!", + ), + ], + ), + ); + } +} diff --git a/lib/components/Settings/Login.dart b/lib/components/Settings/Login.dart deleted file mode 100644 index a66e4e8f..00000000 --- a/lib/components/Settings/Login.dart +++ /dev/null @@ -1,108 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:go_router/go_router.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:spotube/components/Shared/Hyperlink.dart'; -import 'package:spotube/components/Shared/PageWindowTitleBar.dart'; -import 'package:spotube/helpers/oauth-login.dart'; -import 'package:spotube/hooks/useBreakpoints.dart'; -import 'package:spotube/models/Logger.dart'; -import 'package:spotube/provider/Auth.dart'; - -class Login extends HookConsumerWidget { - Login({Key? key}) : super(key: key); - final log = getLogger(Login); - - @override - Widget build(BuildContext context, ref) { - Auth authState = ref.watch(authProvider); - final clientIdController = useTextEditingController(); - final clientSecretController = useTextEditingController(); - final fieldError = useState(false); - final breakpoint = useBreakpoints(); - - Future handleLogin(Auth authState) async { - try { - if (clientIdController.value.text == "" || - clientSecretController.value.text == "") { - fieldError.value = true; - } - await oauthLogin( - ref.read(authProvider), - clientId: clientIdController.value.text, - clientSecret: clientSecretController.value.text, - ).then( - (value) => GoRouter.of(context).pop(), - ); - } catch (e) { - log.e("[Login.handleLogin] $e"); - } - } - - final textTheme = Theme.of(context).textTheme; - - return Scaffold( - appBar: const PageWindowTitleBar(leading: BackButton()), - body: SingleChildScrollView( - child: Center( - child: Container( - margin: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - children: [ - Image.asset( - "assets/spotube-logo.png", - width: MediaQuery.of(context).size.width * - (breakpoint <= Breakpoints.md ? .5 : .3), - ), - Text("Add your spotify credentials to get started", - style: breakpoint <= Breakpoints.md - ? textTheme.headline5 - : textTheme.headline4), - const Text( - "Don't worry, any of your credentials won't be collected or shared with anyone"), - const Hyperlink("How to get these client-id & client-secret?", - "https://github.com/KRTirtho/spotube#optional-configurations"), - const SizedBox( - height: 10, - ), - Container( - constraints: const BoxConstraints( - maxWidth: 400, - ), - child: Column( - children: [ - TextField( - controller: clientIdController, - decoration: const InputDecoration( - hintText: "Spotify Client ID", - label: Text("ClientID"), - ), - keyboardType: TextInputType.visiblePassword, - ), - const SizedBox(height: 10), - TextField( - controller: clientSecretController, - decoration: const InputDecoration( - hintText: "Spotify Client Secret", - label: Text("Client Secret"), - ), - keyboardType: TextInputType.visiblePassword, - ), - const SizedBox(height: 20), - ElevatedButton( - onPressed: () async { - await handleLogin(authState); - }, - child: const Text("Submit"), - ) - ], - ), - ), - ], - ), - ), - ), - ), - ); - } -} diff --git a/lib/components/Shared/Hyperlink.dart b/lib/components/Shared/Hyperlink.dart index d4a70b1c..fc121951 100644 --- a/lib/components/Shared/Hyperlink.dart +++ b/lib/components/Shared/Hyperlink.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:spotube/components/Shared/AnchorButton.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'package:url_launcher/url_launcher_string.dart'; class Hyperlink extends StatelessWidget { final String text; @@ -22,7 +23,7 @@ class Hyperlink extends StatelessWidget { return AnchorButton( text, onTap: () async { - await launch(url); + await launchUrlString(url); }, key: key, overflow: overflow, diff --git a/lib/models/GoRouteDeclarations.dart b/lib/models/GoRouteDeclarations.dart index 894a1d97..cb28a97f 100644 --- a/lib/models/GoRouteDeclarations.dart +++ b/lib/models/GoRouteDeclarations.dart @@ -4,7 +4,8 @@ import 'package:spotube/components/Album/AlbumView.dart'; import 'package:spotube/components/Artist/ArtistAlbumView.dart'; import 'package:spotube/components/Artist/ArtistProfile.dart'; import 'package:spotube/components/Home/Home.dart'; -import 'package:spotube/components/Settings/Login.dart'; +import 'package:spotube/components/Login/Login.dart'; +import 'package:spotube/components/Login/LoginTutorial.dart'; import 'package:spotube/components/Player/PlayerView.dart'; import 'package:spotube/components/Playlist/PlaylistView.dart'; import 'package:spotube/components/Settings/Settings.dart'; @@ -22,6 +23,12 @@ GoRouter createGoRouter() => GoRouter( child: Login(), ), ), + GoRoute( + path: "/login-tutorial", + pageBuilder: (context, state) => const SpotubePage( + child: LoginTutorial(), + ), + ), GoRoute( path: "/settings", pageBuilder: (context, state) => const SpotubePage( @@ -71,6 +78,6 @@ GoRouter createGoRouter() => GoRouter( child: PlayerView(), ); }, - ) + ), ], ); diff --git a/pubspec.lock b/pubspec.lock index 4374a9f0..70e08e12 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -37,7 +37,7 @@ packages: source: hosted version: "2.3.1" async: - dependency: "direct main" + dependency: transitive description: name: async url: "https://pub.dartlang.org" @@ -323,6 +323,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.7.3" + dots_indicator: + dependency: transitive + description: + name: dots_indicator + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" fading_edge_scrollview: dependency: transitive description: @@ -527,6 +534,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.2.0" + introduction_screen: + dependency: "direct main" + description: + name: introduction_screen + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" io: dependency: transitive description: @@ -828,13 +842,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" - resizable_widget: - dependency: "direct main" - description: - name: resizable_widget - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" riverpod: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4c4b00ab..66304f37 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -63,6 +63,7 @@ dependencies: hive_flutter: ^1.1.0 dbus: ^0.7.3 audioplayers: ^1.0.1 + introduction_screen: ^3.0.2 dev_dependencies: flutter_test: