From 5e4c336c4b85218f858904d3e280d66a84226035 Mon Sep 17 00:00:00 2001 From: kconnel7 Date: Tue, 31 Mar 2020 16:00:00 -0400 Subject: [PATCH 01/17] Monthly Calendar - No API --- lib/screens/schedule.dart | 8 +++++++- pubspec.lock | 23 ++++++++++++++++++++++- pubspec.yaml | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/screens/schedule.dart b/lib/screens/schedule.dart index c827f1f..0a3f716 100644 --- a/lib/screens/schedule.dart +++ b/lib/screens/schedule.dart @@ -1,6 +1,10 @@ import 'package:flutter/material.dart'; +import '../monthly_calendar.dart'; class Schedule extends StatelessWidget{ + + final calendar = Calendar(); + @override Widget build(BuildContext context) { return StatefulBuilder( @@ -10,7 +14,9 @@ class Schedule extends StatelessWidget{ title: Text("49ers"), backgroundColor: Colors.green, ), - body: Text("Schedule Goes Here"), + body: Container ( + child: calendar, + ), drawer: Drawer( child: ListView( children: [ diff --git a/pubspec.lock b/pubspec.lock index a5d537b..b0162bd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -109,6 +109,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.4" + intl: + dependency: transitive + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.1" matcher: dependency: transitive description: @@ -172,6 +179,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.23.1" + simple_gesture_detector: + dependency: transitive + description: + name: simple_gesture_detector + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" sky_engine: dependency: transitive description: flutter @@ -205,6 +219,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.5" + table_calendar: + dependency: "direct main" + description: + name: table_calendar + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" term_glyph: dependency: transitive description: @@ -218,7 +239,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.15" + version: "0.2.11" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 7cf311d..3667529 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,6 +26,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 + table_calendar: dev_dependencies: flutter_test: From 8a5b57b14c72503ed52abaccb5e98038e12b38e4 Mon Sep 17 00:00:00 2001 From: kconnel7 Date: Wed, 1 Apr 2020 04:36:27 -0400 Subject: [PATCH 02/17] Monthly Calendar w/ event placeholders - No API --- images/female.png | Bin 0 -> 21714 bytes images/male.png | Bin 0 -> 19526 bytes lib/monthly_calendar.dart | 232 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 232 insertions(+) create mode 100644 images/female.png create mode 100644 images/male.png create mode 100644 lib/monthly_calendar.dart diff --git a/images/female.png b/images/female.png new file mode 100644 index 0000000000000000000000000000000000000000..5ad63c1e57e30ca64bbca2c186c4a236aeb8e442 GIT binary patch literal 21714 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%0AY;4}VB2VROGRZ)=gyil~I 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 literal 0 HcmV?d00001 diff --git a/images/male.png b/images/male.png new file mode 100644 index 0000000000000000000000000000000000000000..5a518d860da9ebc8c32d85b39e259a619cbcad95 GIT binary patch literal 19526 zcmeFZ`9G9z`v=UJ7}>^1b_Qe57RhdgFpPcA9+fRBWG6$iX5W&v2uYS?Da$CzQfLyA zG8NhPeSgmBzVGKxcwWyB-yeE?KF#a8uJbsL^Elqe`&iE6O^kFIPII27prByT!(K9@ zpnzb&A1)X*_+^nYxb+CN6&0+>amBbjq_)B1lL}nAQG=aGDNGbv6cg!C!93MEZu}Mo{bpdGba*or<3<8xjTS@5$vL_94PU zu@}s1BK=IqXFqj$4iYDskOs2(Ba1gYuWIz_xOhnlmA z|F6MglL?ON?k_gopwSB6Bu(#~S)>OHk_2U-j4>ozfdKMWC1oFeI?|p0^Oq z$I=LB7{kN=eBd_on9bkgPUgudu_?a7Do!Nma;Txgbqat6%Bl>9I z>;{A!qb814r4>miCU{iiCy;QBd39>0>4TfX*^36wt$mYCSGb}i3X!7C;+;scL%u`U zI2IZ41Td-JBRE4`8$6;rA8q{9gl7gG{ZWG=;e3=QkDY|nU)Cv7KqiC~iV?6VYKmV@ z|M6w?V`yt8q>_&^syIR>h>ol^1SIUCwwY-zhXVMqc7bN$f8JgZM}aZXcJ4jxYz zWg5Z!7g$V~!J-L-bjkl=%oP?S?DU(6TE_n^ngD}CEuq;r{v9!R3-$;|HMSLf=YNY@ zT#7_i2-IFBZ-)F;^caxp?F+u=(f?hvSO6@_iWjo`pHy#!(eN_?N6tL|Ta=X<33~=R z_f7M^Qo;XE75`tU!h|3Hnf0&X2)yS$I9CPB2T#BWYC@0mQ>B|B`1j!OFWfJTA|JlL zHt8DAmW8#hFC2=jJp=5f?A9t1*`Y|Zt)g^%j6e11@1ddK@C7PR2KT_>52X<7+d8lz z)sqT8!G0XzNZ34tGnQ;6?zx0Pi{l>*-_dLExI(bcXJ7V?0_xwHCx6$KU9r7|_0TYVp%iy5zxPW4_%Gh!Umd6@05Z2WU6t0DGOfh(#4 zDH9M2mV%4oW9k@-6AIT?qPoJn+MwVNgiPX_|6wc=a?qPC2dSqq zM-F8Jz1hi!k$bi?jP zQWf**NBD5iLOwG)8=3f9-tQ!DFbYY+IcuZ|L$5ICpo{6iD-P&CaI#bnS;j6OpNRWW zHy2S*O2z(f8^t=1bN6fnZzMb;@8MNgFAo_w^r2z2i)Z4iU}9fA-?tB?%Do7)Cm)DO zB!PE)2j$TX`A{nXjUuCm|CTd1+4PXGML~%H#s@%UtDA7a$k#Stt$*QrYs%KMP5sI3oCC+U@RF%PEPOVG z5PD}dCA2rvl^=c{h#X_DGM0TBpEcEE(OYx$%6IZ4!U3}$BB3r~hZ%Bj3xp3V8{1)0 zn?m_SXwZxSt<|j1xupv2@Du5w1v+AWL|)a-h&k~OF@xv_Eb@qU_p^OtS=5`7eQ zN1EAT*kacu;BDYDXOgZWWbqvJ;eNgNNcfBW-s^nX` zbhVnOgY=KF9Y^U>G%YvsO}n%tUqyKCDLj!jsJRG=pMWij#j4HuiFg=#Jf2F{xZiJk zUheg9Uffahxen~>;+3yCL)a_uF^B8dj;zy$AU2|%p|%^&3RwuhF+1;H#3eRk-$s zX{V;+uYYh3rM0v{K4~hmllp-;W4%FKsV8la(5w@dQB!Y@#Tn&}=3#*{P`vFhMXc^C zf5)k8d)T!p!v(taNXF+6IOm>4)$?G!g`R4;WQ{Gy zKuK@zt6WM>a;F| zP`=6DFi!aD$;6kXdb+vw66Zt0&+)SEl+i;QIFvzA*G9yh0)EVJKT_H|IC+qlcudUu zXS=PICpLa4jo+PB+)ffdgwm*4#*80Ds0PW|AycI(|3atjc1l9pW9Sc38!|S9n%9KwCy;gL$doV+FG`1v! zeUnIiwu0dYis#&Pp=w^=gwlXWk+D5vf7?aEi8Jh+AWm4XaN*Admyo@;e{6OcMyXXF z?u+*3SbV@K2~D0-;O0{APh`TF7`bV*Q{zaI^^0=EHbj98{k$iYbVVDFWSimoxLKvh zAZ3W&vqb6XdxLpM(XE%fCsD#OxDg%^HRR_jZ;LAxNb$ptLVGo(78z8r|&3$qg zX`{^4{;Wy3L%#RCP88C>W(+V>mo!igY8*V7!qtljIYB}%pN{c67ZAkr%pB#U{-FEs z;{XJ-(pL{&kw~Bx?=gNV74o=V09R08`QgVRA0hvWBr+Wz?|ziQeG#4p9d+Zw31Ln*N)m> zi(p+;Pf9C}K$FR6l7aL603~z%J=+jgr-rG^hqx-E>+LW5jO%xv2x}Uxq}`U*zf-SQ z@?6^`per*ycq?=C+D{ugc7Wxkiq{7z`GFfqoNcPn29F7g~(xKEjnP|hDuYzWoj z_v0#e zv9X>m?uqMpZo7UFLXP#Gf%)KPtra(H`+}G4{J?KM=sxo*+h4XaT-l)hg1%vymgQ=% zAuI3g7Qbt6r17sH$duzWa^z3K5;h_t#Dl;7_$9@)$`R)4L3MG~-rc2BTl(It^oG4+ z&h!jKR>huEYUvr%Lv}Upk}h>ulxW@Q>K+~@o)e5R*0$vF`JS_oI_5Dm>LTGIE88~V zKWcghZ0XW^841k0Doe|6to7hQ(G-{=F3}*l$jI2^a{WR-(w3Z6cIyL>mYm}!`MEI7 z>CN3NTQjrl&3Sy+!SXNd%t2n*hGyIc)S}>vJ9+>xakt|6{zlGV=Zty-i&8;+OQQ`c zjE~MN(Ea&pmA8HIuc?TcEX46I>1OGQ{$ZTNd#S`W+Nk=9znVtNrEO{x%b$zlW0J4B z!O+eZ`FC5Uq<>`Tzr7u~u4HBVqV&+W_j)_`7Ho)VpL=^k00GSg*+IjZ&r^GYPDA#tcP)RQLL9^5bL6mJ`#y!%T5Hd*Sp`YoNo|ZnJE*@DtgboJ zKcSe*RtF142iuO)joU@Ud!tROG!S@2LgZl6hER>78nI#sKRy$S5JX3rAU}O+FUriN zvY@bCeuIEce}f!je2N5vn+w2M3~MoM>pC`hn3sp9OnRxmIH9m66p1CW@ zQzS{ry^;WUiS^iHwVuGxJ*kYF`d+#Vr|xSZ9U<+PUbgrb$luy>(MTE0DCT&`dM~Os zXRGb88Z9IS?2Yv;>(;<>P)%ys2PoK>dtsz>Z~=cc|DM9`OCfN0bgvFXP}28$xQksD z$Lyf*HTi=fjQ$!@;kb1y9J~OFjf^gmEWPkfR*Vzpm|5mX)00Esrl?~~MW!ZzJW2e$ zL}Q!U^JVSt>gP;HqtH?4NT>pA=;@H*x`T5yMNcDwBF51bKmLKuwV2gB>av75)8vES z7b3A_qGl#Aq(PzID;-w(5P+{IwWIlM#xUM=SfnS!NESp&NoXsgVTNLlnh6070X%D1 z?rrh;RhH*Rq%RUeDbRo3RH{kviwxsB+z}GSl$%vC9CS|C-j^uu`kiCx=!jZ`$7_%1 zLvdE%Yk#1J@$Zszx98kEbEi(rcV0ktG82nHqA@F{=P%mPv+Y6dW4MPBl+Dg2kO@thf;IL z#w0)pcBEDCJJhHeJ4p-bagjR|V+AIaOc1!Xq=Z(bd#?O`YC<+hi(&2oSI)=q%YNv5d{V6cnVG8NDV8QV1bHKmXk7J(`#mRU^#K!ekI< zbh9KycMgZ@Z~fSPTA;Qq{Q!i)A#W~UPIxue|ge|ZHZ zVih(tsjo5j@&Sb?L0|tX3X}=FMsf&J*^RW{4gRIsLl^MI^F3A+!*_(aVR#>yj7SBS z=N9+N?1a6nOB5DNH}&xp(0L)!8-gm$>~2V6nLI!w0(J;-mcPx;`u(m{t%KJ2({|$g zq;i*o7VJoCL{0l8(iE%T(Y0R{mik_gTwHV zY?>hJ$pCH|VQrThYULww zrfEss=afhum8|IM5^p;_yB)yHLQwHgd_7DtZilH=*mR*}izkednTM(@C+Ws~AwLyqU0{>oOkEg?RuWyI>KNa0o%3fh=BycMF?eboR zIjWDRK0h51&HR~;lo6n8YDv)(Np5!YQ`v3xdC;ohrhP|HtKDKs8gPz z?DNFWUK?b25E zQ6Ohp-4d5}${bK;%FwVkN2Wwpvwjc(bHN1x6X}1*A8Jm{p5NrLQAp zFh2WqIey|v>fHAVp05UWn}lMro7W3_Af*}I-fAASQ`Qt85VXtS%`dqyzhyWvKwqCVr4RrB{!F(Q7-?c&lQ5hgB8gXDEW_ zXc6S%0YB}HvT8b%^3+d`pjRVbV@p5kz|I*G21CakU*mpHRNe3FcL_};b0VY+ic*8+ zFSfJxi%Zx$wFm?NvtG;%x!zl1SVL^H^azc=j zW%dc-0Ny!aa&4FWk~7Zxq2TAvvu>n2nNM*jn1vxB(KF<+TA=q?4dWk8!KK;cYPqu* zgx9A-2gKU zjqN#u)X14-rQmO;q_6i?nAG|0T$bHHAW`I^&y&NdIEo7PXt}OM!v-E06irBZwI(^q zn>D4noZs2<`&B(zr{{%hTf&MYKL-a4kUF~hnFt`aK|#3saz#)B(*qpbLXN7c(zzg{A@8m?Xp}#C@!n67HqqP3DIZC@yH(swz)S?7ydwkt$%1mLODlyz`cdd4s6zVZ6kPtoJGs@; z^&^+(&NuE;KoeMYZ}MoCE1r+Oc}BON84gP(*w**t_$kfAy4@;ZH>7>BEdv8gH;Zs? z`n`E&>_+VCBF(#e}DZ?fML@=;xn+A4Sw3T`;+Lh89pD144(-vEyT^8-t`%YgbsmC2$FR zyQuHns$b6MK1tJjcaupQm{2M^erq~KdIRM7p9qvgA@N_8meJ0lppUV}huV+YrdPjk zMzIl?&~3!3=+HMr!OtQ3WtK-Ax2+_tv_QMZX(UY=w@DYx5%hCv+#zEc4N^@}NKxhm ze}65xX6+lfRB#Kw?p#h<83B3!4$|@ZFy{jPG0P7hle_$YUt!B1(2Oe36I5AT#Gg=MO=tj9Aor9oUq%Ge^rp41`S&s)dtN z)HMjR<^fn0mr5wC-{Xi+_V%C-Oz2Hu9uX1ND%OXz-&oGdn3K-FUVArdsFw=>;QdHG zSkTi;v5oRn0O*7?fhJ^f32Y7V>aHHt?YE;$|8#oCNWx)x1oislfg2vwOmVas#nC>E z>}(Wx<9_P>!M#dPw>fKSSaOI1UpKyFhdAm%P)BTYlG%Pf;dT8AYy5zhY_waq z%Ll>&{RR>)fY&=e&xQ!^b)n`p{3+R$@KzYODlMh3mh@ahczHiRZfF%WXhgBjmP>cD zE+HFoJLg`y&?VO81-3Ca=G+v zwb;36bUt)D_1hqBQ}&}=(#un>cj}>GxCL26!IuitocMRAdq?DxF~yf5cgueV(+^gd zUR1DS$Yi91ZHm;!AM;aiUg+}@Y-`bAC%4+lSQM?4h?7a2TkXW&bbg>9R{TqUi{%1h zm@LVt_C+2O4W?KI|H%K+a`*sGOyzBIF<2R2o$0zIRo?{eJYLFHEQ(=#CW@KH{RtLyf)oG2L|r!0K9*91=T0d#^k7(>Wc zDUq1&7?tG*r?$ni`#8ZKH9bxf%sQvG@WCh^9vMlSe{OnwZ|vsei-Q0%cF1cvCnbCe z*Y+?zD|&`al0Dn`=>2y;oF7wCZB-?oUog=JEpOEN3J^pQM<#L@BcYqf13Z$yP zNut#L;OU^SeN!_vz8E$k?B%=U-p*oS=u8hZT|{`Zm2%Ujr|$0hOD;X2i*9Iu<*`zL z%=TV{hi7+KFYiCYp;cD>px$@UtJX98rg!WUei;G$q*n^JN^Z_{;6R47?hW=u3OpM2 zoL_}E%XhI{ioTRlh63)bUn?bPDRXSRVG}y~^7f-g5?N zXvU_VP*hiw>)&kE)0=v|?>>R>feeFmWW{U1CO;A-?G2UMt2XU>;UJ*BN@qVb?OPlD zI#YQUJf#dVzq*!T<`X{hbv?Lx){`!pAFfC_dG_RSrd_PB7HKOg7*LrZsE*f08h9%E z=!Z6lY*r94Cq^#m^p#9s`=kZ)SB(OoNdWB=AUTud=l1K*Cy5qOUGwUj)MK_h_4Fy) z`E`B}wr`2;tL%Dk6!}Ph3$0=vsyp>no`h&069c=yU$0Y@fzb36<}1Sw=3AgDP%EZf zD$py_C2{g(+wpDxS~j_T24GDpp?f^loMt`m@Mr}O-{k|?l}$KXKM@%CcR1w-r?>YN zMJPm|_UVn@%0IO=gL(_p7BsmK;59}BjT^oT{R%5QTuSI-IY_0Erpj}?cJ;i69nEy0W5;SN6x8hScUZ>!)##puvWmT;uat!>M0i70WK&N^;;&-LF2$E$ojuduF4pZ}2aj!fb5 zpkZQ*LA^NVsnk}_?Z)(IegsrpDAg9esqlHd;7UvBqv=_pbQL{vY?8v;O^r{_y}sBZ zC(R_|H)N%NF1`w>JcZ%a+@gZ{>2;(%Vfy>~T!bdl58{+@((>`h&Y|5$EZ8CritmG! zo`LRhT(QHoiG5{m^furT+0M~EtE>crds0$<~Y|i0`2CwLF4@rj_?G- zcF8MT_Fc~CvK_0+y*7T6B(ykYh`nV=?{iCO)%5J07RAJ(e?(eUbN$oBW8BFnr?M3R zUd`e_NV`v1S!TbCEM5H8&+9#ukUE5o*8NG*>7mK#2JF@6OR}DC%sFWDN^QsZ=ksPK zc4-Np^kP)w*obWNIBidALHgz$Hm^XV8g z391V5FWK}b1!Q0QiMe*|k~*9ni_AjKhEwt2Hc$4}7gT!-kRULC$`Y&ZQMo;%vzjPbrJcdl*?i%Nc&EvD__g?dZA zR{BV@F1e<9?!v4&?H}Y2JKmgAqNP2G2U>0IbUQPX4nG!+)UXzgEvI*q)^M94imtJM z$a;yis~P&CWn=z)=#iq~hxt_U*Md>*nmv)Yddb*@W1$iOF4$FF5@Yb;Eo#S;m@w`f zd{MKFAU-!5nL_cYBF!>GyI|t#uS^C?7}U`D#d8%6ce;LAAGvEU?UgR4(Lv9$#3{jS zt)-q9V6;Q7jh*7yjZXxJ90+YqKeYV8!}-QL3g=vB;jlyPzlx zvMybcQF!kD%Pv)sIHY^C6~Qfrwu>8D&41HcYVmd$O+H&uuMIt@bQ+M%#UV$K?hP`AHEfoGWk0IT%unu&!fb%W0Mkm<2o(DJ#bkMPH>sqew%Q9)M~x{w zvlKgDRv1<=nZXM}1O-$_fOPzOIxQgKaKl@$iEo2S5R`jtV(4XNJdalNQvR`jLFQ(A zmC~P1G6;Dy3DSlp)P*6cRo{PJ5F_35A(ZZ`unLI$N-WKm1LeHXYEi!ODf`}CM=88b zG*UV>cfa6@Bme#{->OFwz$d$C?Q@#%2HfnY59{jAgLQF2z3o|wgcH{;=|&X`dqvjs z!};*I-*PRr-AbzRZ)DCe&L*RuV^WJavO``wG1g;U=3gb%oqKrBBKcxwp#%r$l2@`cUuJC2Zq9&W;;nBLEO&E4%i5i@foUielJlfuQA!O@ zk?G8klOo?Ar)KP)V}?GGu-RUz(Z!GYKBbdoHGtWtHy5?51Z9z%_CQ#6=mXYA@fX%S zp5>NX+?r1;ywIKP%b%)@_hJbgGN$kO^*6VxN|t`dg+9uR@04$Uvux5|JS(t)dr-3# zjl;HAruVj@dMOcLAg9*sDk9_YyXS1rqtNuw)}i@)cKRivP71Vobh?h48ec|Ut*qUw zK_X7?Gwy=xovYC3aYx;b-!aS{nXjc2=t?aTS9hUgNiGqJVn3g|iuRa!SzgT21^d;8uT zSdSgb4J}jU?82I`FP#gKaG{Ih-U9|Ci#T)S5km!c&nKu}P7Q%KxcteKMTS7?PGOXi zpv+M1ySBe5pqwJ9``95xW}~Auy$2T`bJGJM^3sFKS_Mx2iYyB*15v-SV8c;y$clZ1 zOl?~5cBK>JMznc&s06^tNVGKckm7ocQnsfryi0Pua>VCBME6-}S%lJJ@Ykavujh9Y z$k9`XgmV!Sk%}#|e{*5)tQ|ZPEb8|xP$$aM^Y9E6u;x-##MCp;T3VyFj}3)l?wBmM z((6PiyLAJ6C#-@UwkaPvDuf)c$iN5jPrSH~-z z|9sJ|G*1;FuV6W|TE$D=?w^HDq78t?2PNgsFqAHsOlcACE~%#_TLxHG31g5X^(HHW z54w&b^MUvBtU zEAIo7Ay>psDqK(%Nml8>yg<&nZ*~pAN-+JFFXDaCM}Vp?)0X}$l0giIe<$^*gPpLF zpD2+!NHUsVM+1{xq6iv<)yRbIrk^E_nvf1fFhP)bTG4!AJ5 zolM(x)}rhB%@3@fn*;?h+VOQ7fbJ%v8FSt>t2}pDdf6rjsia}$!NA-_jAkRnsmzgZ zCH(LK%U@%ipJ*)^jYg#C^ul)^CP!wKtz?ON0Vxdd9(?4=Q^OXGHLUggB&|}z7oBhv z%=64i@mq5zh;!<@8vq-{1xd%KM)h`B(y&Mb+m+6C2SnTwR8MW*_$bFN=Tqi8fDuwK zu+>uawKs|4GpUcEz=$0s=bf(}$RW;Lj=3TQg$Sqa|1eL2o|@Qok(F#j_B5rI=jXCy z`Y!$EBG>PMWJ(w)W~;Frg-eu#=^vf-)rm@1{dDUz3rpggG@yCcFZGS$oiffKrp`$XBhOcFz~dl>Dr1%ZtU+roP~a3R?vxh z>#kx$NeR1Wh}=TX3jNvHJJDRfZg$fUy4E-lhtL$M{8^Pio>p8 zbC^O2u)B&R!g|*9MA-XdSp)cRnA)YAm>W*bl{6Ty3hizyka(qhL5TC2~dHQ0Y^S-(cw?vi++T!0y?fAw%+3 zeb*mk8Gwl_^l9kf)b8+I10`7Bm1OtROS0~KU?#JwkoLUT^c&^3g2~!&Y+__|vEdhA zkJO7v5C+Y+_kGAQPttf^8eZLYkpgWjM*MIza*}()S+Theb^TuqaANce9Y6n9 zCuRw(^91_-*`^`qtK#vuM?=H0RgzH?e*AzETsOSQ`t-65*zF~>v*fqg&&3uQx>2ww zv+5stM+vg9*B#e&49|SPny?Iuu|PcFW6BH{$3rmi;j;{UXM{i$nPNe1Y1bcq zvKI;XgfW@d8jrW;U&a(OLkj6K_n9h0xcG4;dWg6Su-CG^<2JuDqmjb8(!V-YfDgz) zR0109hC?0rUTv}SodLw8SOcnE$LTs^-PmuPaiIn9g?Pl6q-n?gn>*eocY~PlAOq)w z{`isjC5?OGyZvZlm(@qWoZlj4B*7-e=h?EPs^B-i~RY%K`5V2aP~TG|f&QJe;hZD~qmBg#`Hs_!Tx5$p9XbmTiql;L0b&ET7=pyr#zJOelxiJ5T7zsOnBV1-bd72@u# z6Zr`O9Z;wM3D=#Q8oNFDA7^Q`*sZJPy#8nU*i;Wm0FGq=7?1m6F|MN&D@EEa*t(qIB6 zL}FIX;MBrZ@6fC<0pgJtsf$hdCv4`YNiOWw#{i#uyJo5D}*atB=k} zn!U!UVvxhdRsQR=Bbovt#Jqb;Z|`2=r|9!Cv6W0EqguY(WpHRgk$pA&(vZCO&*0gV zvD2VTjdhmWJN!$3xSbih0DAFkTx0?LW11yBBOQKd@2BV9jNbY({ZEU>Ixt@wt&f7} z9J3$riYWAHOlr&F)66`K@BCHVGJH#7b5Xpig2`HoLl71@A?4pJ_OWZjJ{n*e+#}_#3lAn z6Q~CcOUhveB^4Xw=hnN+8h}0)tKn()dst?;xu=SkzCR(cfQ0WhWT8)EQmRnPY37;< z79clTTo6+eXCf6C-y(as(q{|h0MWjLWz`-zDVe9Ge33?EjTv$cK8AZZwc1}X{pbEQ zv>+4skT|5B>*L^%=N46EM}*9?@y@YXSm}Ah)m2{JMqfRrPu-@6!1;b6N!QM|s+&m7 zMcH$A4+6>0K-GlrHC>FZOEU|!s^q$0c0LApvLW-XmHDZQCd*sm8++7!Wj#s%3JGHG zMzOrS1N_yJA{v>|Pj+FHuvQ~yzN2t+opTXlPEG?oPWIklWEGRT<{%t=rP`k8<2&3* z9^k+h5!{G@YYa@`FZ-tvfw67)dlxO?po9|AdfEj4x20flT#u87Jl+UqlC=mLL5<=f zRieHvdR9N#V#?S#F5riwkSCtaGV`2bK8G`R;)*25!_Y)j?emHCvYR#RMYz|PWc9qn zm%Ft1^RzcAKdMTLittznqu0S>Q3539$(&OA{f3tHts~4=iuY*bc}P1d8y9;;W3T(n zWvXs_m_ODze_O?>uTmq_=J>@=e!hTc5MIsRaF0aYHdrteu36|AGi2Kl#nOHgppjYyggSS6cOMmb1n9XFukJ0Y> zRC<-=D>F@+?X!{#rllB?ny+BF`p0%D?34Lb2;>vXZmK~~HC2n9`b;5N43m-(r{=5W81H{C7d53rE784^PXqgUes|DgMqEc2CZ6ilUp33xQrV+>maI0Q{&of_V}1}~aj~gAF}CciJ8IFE5pS`=D97VucU&;Fb-`CZ zV`{O<&zIeaKNU_niCB5lsbJ7kZsef!`U}rDGJGTvY{!=r#G0HewgXoN;B{;u8p82& z^+F%|op*XxI4HkTJ-w=loK8bpm&`yN#FRvPBnyzSYU2OOg#4>&5A*)yw{J}E2(DSM zWNRXMArVPB$sNzRcaKC1J>Qzat{Rg>nR{*zk8iN=^tW$QQs7V1?p_IN36MIl=*fBx z+{zbr7*ijN>8mSR&pf45-S440WtNJb&v|F7*#0#n<6D(V_8_k6`rnJonn+>Da%_iK zH9X_9(6{;Gl~H1%(6p`sh|pY+6pzs4j{3!onQ@sba^R>`@g3Q;Espg&Ki;UGd$p$! zcZvhP+Z^`s0&HFIf{mVXv`%v3XXad~#FbRvrANt$FW$?rgQ#Mo6`%o%;NNy%ANZz? z@LbnIT0+Wu>+BCu2TRus$dx_@==+MK8hxceMUhd$Ljgc{2Vh}3Z>A^sZtr-yE!}HF znsDNmvdohQS-kEvY)qY8Df^5P1YltYv704~1V3C@c>3e*A4Tws3Z$LxkDJ+xg5;y^ z!{`Sna_@v5FD5>cQ|`AMJCJ(9@~G3e65jKO5ITJvCbq*Ux?&Z%19t}#tNjNYmz8!j zr29{(^2pDC;{DXI#7Cahoc+AFv+dT7K(2Y(-TuiyufN<-2k8^*YTgS%0Fakpi%*z* zm+#rOuT1`@hd`v=?OmbN!E4OMajTRZtA{>3zQ`v0ff8)q z6jC)C8C!Zh}p% z*n`|vQ00|3aDLvWVcAzF$T_=_(%s3T0N@L#eP;KIQ z8|3sDKf~r;kK+|zRZv`xBXo|ZFZgv*Z_B=6eEg0Y$Y=`8?cQh=dr8Dx6}FjN=JJ0HmX+ag98P&61d>*>4XvS!(g$Q zd%XUE*g6wL3_XX&fCAo`?)r)cY^H0KzyRta&`?5=*SFpBCekVy41au zY25{FPH@5FuXx9ux9iHD!_~h#d0ZJT>L;Y66XxspcR>Hkg<3kH8*e&-($PZ7K{Qf3 z{Oxh<_UCy2$aztL8nz?MfY>R5-4p~rj?w>>aB1Z$Hq$shs5AziPfKU}OnWMMK zgOl6!4f=Xd8{{IlpigJtB?>9OEaTu75k4*>52aDFDC#_#mCL?7CNbXn8@b1hgB?1xU6U*>J2<^laG>`j$N4w7&;+NWl=fS(Q>KlgmfLmu z?V^r?O&JkpIz>?X@tyPotZY&xGZFVmcZZ>k8C&P>Xf*rz#SX@q3>$L&!3nIMn%1HK z{n4B8cW>$?^-=>hrV=!&ZYZ~O(yLzC4<$BJFWi63KZL@cnEi5eC^)_%6J4ZmS(aR6 z%*2rxuj%Sul#gCXV8ENSEIpWbD@;<7VvNkClJ_r?vA$u$p}eS&bO#hSoh6nG;lqV^ zDt_Jsn+m-;zf$PLz=_^t4fjD(BzEEKOJJr7(6EbV=!zMB%)J_6R=%8M#eb;|n?^ZVtMs5>b*`07hSgxKwYCbwHPy9POA zba)I^M|QMARe7$2Qaf^cKe@EP*R+n3G5487-u~I-M%pvw>wOtax&U1lSoLbbxhbkf z@3~9`TcBWFM$RlsBxc5eyajU@VW+0-x@R4DQs3E{ zL*4GTJzrrbolAq(^Q@#FVCmbCmCyYCNrG}VNTU-QZfRX~@ok81Uz8GJCODM3`jLS8 zmmu#eFQR${A0B;|U5WjBTQe|M z=`>)#1%y0b(&_ktIyvf;xUUUk5jTTyfbs7muz`0kbR1HXf4y zCh!cbbSBeyGZZg^PrewdM*WkN9!KC=&Oj7+@6aE@M+)wjeT*eXxo+*nONOLOi) z_Q}6ta03#0>9<|yTu`X%trYfU={+++T8JR?YR1RF9GktCri~Y0Zyv3rMQ$jOKVJe1 zVjZv1s~)&Fx_mi^ht1gi2nPfY09Tc^=zE{A<=a*gv?ye}Qhr==N3)Nx5to@vuwNS(0NO z_v9kBx{=_ebnY^0~HTcH3|$yflN8u}BX3^x2q%kn(W|$L^K94I$$O zH4A~S#?DTx!4Kq(U6SqFmL`urX%RWeqv_--hl1IhFfAPe1qIzC`QHL)!a+4Z$*x|V z&nUf26h~~tLQA^j9fO1SqIk+ya7nxJqa${dLr%4q-EeE@6(T}f{cwOYA?%) zIzV}I2GRy{meZGW4i%}vOnAiAkMzBmW2toAh>;BJC&X%)g!I?j9xtz(C_~?ZA^qX7 z@Yc)1LG_y-{~C5isY94%LH&SF$QapXzrHkHT0$FiW@#xrB+>Cl_Qh0i5$cvqN6ICN zGdkhU+GtS5dRswnj5vBAF9}9XAE!i0^9Px|nlA3?oNpn1GF$d=r5v+cF9_uA%^wrl zKZA#fwlExArx=VT+YuFP=n4Y`k<_75x%j2@0#^h6v5Fvxc7&H_oux@SRn=um`qAkA z)S#=eW>IWgYCBbZ_(&}#Tp$M^ABGWdAoIG?QCgX8^&}^9HVdR+wH3!r+OE*cbEB{o^HX)oGzvdV@rcz zL5O{3qVXSD4jjLU2AJO7f0$zN+j0CC)ZcV>aC>x{mvnK|gVj~>v^28rxVAse)*1BMRJ7@vk??t{f z%`zL+eWUDXF#E9Vl73>Obk-iu6Ej&g+E;gWt4(USN;jo2jr+`=T*toeBP!vONqzOZ z;dHO5Ug!~RJTCWAKG5|C>wMquFS27y4r@uwJWJUW6R4k4I(_yhx|kCvS{wkO<5QLL_$6%3=y`cMxil!lU z$Zcn8z)`62x>w)7DgFLVhDHJjX9J21n)l*)81ig$JILU@8SrmS$d35U9h&w(seu0Y zW1JsKCI3pj4%@ZzsuA?}kn1)V|CbMWUG0}b{70NMa5o{LYM^!GVIC{Q$b(g?<8kabk|77Ar{7qbHKB|-&4Tg=Pbngwfyr=7?Z)FUHPdzOUZ&xR#^c{& z%m8H52)FwdU~|ie4U`0k@f1LllxTsIQDc#lSMt{Ds$kXu=ocSze&-RHA+#_1R~vxBULczM4H zo-uGY7pg_rxXYNGd%|Ln<&0$n-c5WlJu_X%W|fZ$z8VKk>z*zN^>E6Lw8Atfe=Z6= z4sOL}2OMqh4A4m&Tl_W^JE~meg?vKn(y*Sae98keNj*8>u8ZRx4a?<_!l7iuog(WW zf4mi;s%|R*y@MyOFLJ-Eg+lho7n&XKEN8hHr`fNxKZtlvmU&)qH6cM+M;ZH@c6IA^ zIT*ABx0u|q=k#v+i-eW zZJ{}q^vMih6OrJEPFZj;Lo&qMpOS{{;-Z%JRCzmM}l$ThUN&PPb zYSXT(mr+RS(*)E-!cnFd83dDTKY-4&H^7XrQnSBRr zO=a-)N!@sBG@s6AuzTv=8n4!k$j;IM6UYBPfxZGchU`5D0I%r_JtG5q#n4I|HR^b3U05zk z=0RjVgJ|FP_X|-i<4 zrLQ~SV$$J%eXKXiUX~e>YYSkc0u82EANA$A3TZ^9TULBwGMI;{^Bk(8lzOhGX<^9N z8ci!B;x5C|D6i{$KjEk0xWoD(ztm+Iq!NzT9{;`(79rw*`XT%u{`wy;xN##la%Fg} z>^zN@uHFLB2$g-fNq$W&eX_iv^2`Os0e<>k4GCIFVuf6)n zvlpMbvb}yy=AR%$P~Fc;&ZMUjBq4i@Uuj_X>3Riq`}G>aG43*-tiNrPhL#rTGe+=| z6GJetDo9|%cvpytg2rH6K>AN9Z)CNgVb)VDxMIDVeP{Ch^7qk|9Mzhc^YQVYz=bz3 zSqXYf!}Njr-r#aw!K)}FjphQ*PVc*Zq3fmj2a(Y{gVQZm>+UHhf$*z)vSR;d?9 zO*~sq%OK$pN4NJmy~0>t*>UalKW7_L!#EzutK#2mu02R!A-%@>4*hZdkkfW33YrE$ zt0Xe8SPQX(8yPjGQ?#Qa3dC%pXL@w`vHo2C`n{`@|IfPa#m_rlytkzC{_E1JueWT$ z)?F0zSb4aQ&yLOA|A4aFKGXVLPmb64Os>hy-DDCt>x%mR?J_#8(_~&)Y^dD$e(TqJ z}HT)WG8z1%}ZP^ty4XLk$`y4oS!C@7&_9X8SC;jQ&+zwa|X+c;64=e5Jh z^}1V`)Z_b#KP|On_dS=r=gAX?tb|Wb)!2>pefiS$1UQ`%_3p{}HI}tS36H<8y&m@9 z^PFv!CeLr~3*R3P>1L^bj<0z6>gY}fU?Evtklg$F`@R3$-Mar+2)s}KdVg8{bg#8P z&G_nMcq0F9|GBqWnccK5cklN)Xx0X%T~Nk>WUyhtl;}M0pPf(O_otg$i9Z;Cz|+;w JWt~$(699EkbteD- literal 0 HcmV?d00001 diff --git a/lib/monthly_calendar.dart b/lib/monthly_calendar.dart new file mode 100644 index 0000000..8de1bbf --- /dev/null +++ b/lib/monthly_calendar.dart @@ -0,0 +1,232 @@ +import 'package:flutter/material.dart'; +import 'package:table_calendar/table_calendar.dart'; + +class Calendar extends StatefulWidget { + @override + _Calendar createState() => _Calendar(); +} + +class _Calendar extends State with TickerProviderStateMixin { + Map _events; + List _selectedEvents; + AnimationController _animationController; + CalendarController _calController; + + @override + void initState() { + super.initState(); + final _selectedDay = DateTime.now(); + + _events = { + _selectedDay.add(Duration(days: 0)): ['Test'], + _selectedDay.add(Duration(days: 5)): ['Example 1'], + _selectedDay.add(Duration(days: 7)): ['Example 2'], + _selectedDay.add(Duration(days: 14)): ['Example 3'], + _selectedDay.add(Duration(days: 2)): ['Example 4'], + _selectedDay.add(Duration(days: 27)): ['Example 5'], + }; + + _selectedEvents = _events[_selectedDay] ?? []; + _calController = CalendarController(); + + _animationController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 400), + ); + + _animationController.forward(); + } + + @override + void dispose() { + _animationController.dispose(); + _calController.dispose(); + super.dispose(); + } + + void _DaySelected(DateTime day, List events) { + print('CALLBACK: _onDaySelected'); + setState(() { + _selectedEvents = events; + }); + } + + void _onVisibleDaysChanged(DateTime first, DateTime last, CalendarFormat format) { + print('CALLBACK: _onVisibleDaysChanged'); + } + + void _onCalendarCreated(DateTime first, DateTime last, CalendarFormat format) { + print('CALLBACK: _onCalendarCreated'); + } + + @override + Widget build(BuildContext context) { + return Center( + child: Column( + children: [ + _buildCalendar(), + const SizedBox(height: 8.0), + Expanded(child: _buildEventList()), + ], + ), + ); + } + + @override + Widget _buildCalendar() { + return TableCalendar( + calendarController: _calController, + initialCalendarFormat: CalendarFormat.month, + startingDayOfWeek: StartingDayOfWeek.sunday, + //availableGestures: AvailableGestures.all, + events: _events, + + availableCalendarFormats: const { + CalendarFormat.month: '', + }, + + calendarStyle: CalendarStyle( + outsideWeekendStyle: TextStyle( + color: Colors.black, + ), + + weekendStyle: TextStyle( + color: Colors.black, + ), + ), + + daysOfWeekStyle: DaysOfWeekStyle( + weekendStyle: TextStyle( + color: Colors.black, + ) + ), + + headerStyle: HeaderStyle( + centerHeaderTitle: true, + formatButtonVisible: false, //hides button that formats between 1 week, 2 week, month + //formatButtonShowsNext: false, + ), + + builders: CalendarBuilders( + selectedDayBuilder: (context, date, _) { + return Container( + margin: const EdgeInsets.all(4.0), + alignment: Alignment.center, + + decoration: BoxDecoration( + border: Border.all( + color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green + ), + color: Color.fromRGBO(179, 163, 105, 1), //UNCC Gold + borderRadius: BorderRadius.circular(10.0) + ), + + child: Text( + '${date.day}', + style: TextStyle(color: Colors.white), + ), + ); + }, + + todayDayBuilder: (context, date, _) { + return Container( + margin: const EdgeInsets.all(4.0), + alignment: Alignment.center, + + decoration: BoxDecoration( + border: Border.all( + color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green + ), + borderRadius: BorderRadius.circular(10.0) + ), + + child: Text( + '${date.day}', + style: TextStyle(color: Color.fromRGBO(179, 163, 105, 1), //UNCC Gold + ), + ), + ); + }, + + markersBuilder: (context, date, events, holidays) { + final miniBox = []; + + if (events.isNotEmpty) { + miniBox.add( + Positioned( + right: 1, + bottom: 1, + child: _buildEventsMarker(date, events), + ), + ); + } + return miniBox; + }, + + ), + + onDaySelected: (date, events) { + _DaySelected(date, events); + _animationController.forward(from: 0.0); + }, + + onVisibleDaysChanged: _onVisibleDaysChanged, + onCalendarCreated: _onCalendarCreated, + + ); + } + + //----- Creates event box display (mini box) ----- + Widget _buildEventsMarker(DateTime date, List events) { + return AnimatedContainer( + duration: const Duration(milliseconds: 300), + + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: _calController.isSelected(date) + ? Colors.blue[400] + : _calController.isToday(date) ? Colors.blue[400] : Color.fromRGBO(0, 112, 60, 1), + ), + + width: 16.0, + height: 16.0, + + child: Center( + child: Text( + '${events.length}', + style: TextStyle().copyWith( + color: Colors.white, + fontSize: 12.0, + ), + ), + + ), + ); + } + + //----- Creates event display ----- + Widget _buildEventList() { + return ListView( + children: _selectedEvents + .map((event) => Container( + + decoration: BoxDecoration( + border: Border.all( + color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green + width: 0.8, + ), + + borderRadius: BorderRadius.circular(12.0), + ), + + margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0), + + child: ListTile( + title: Text(event.toString()), + onTap: () => print('$event tapped!'), + ), + )) + .toList(), + ); + } +} \ No newline at end of file From 5cdf2549dfadf67e9a4aa1e46027675473661a99 Mon Sep 17 00:00:00 2001 From: kwainright Date: Thu, 2 Apr 2020 14:01:54 -0400 Subject: [PATCH 03/17] Twitter - nothing implemented - setting up testing routes --- lib/route_generator.dart | 3 +++ lib/screens/home_widget.dart | 6 +++++ lib/screens/twitter_widget.dart | 40 +++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 lib/screens/twitter_widget.dart diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 3e01d5e..55004a4 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -4,6 +4,7 @@ import 'package:capstone_hungry_hippos/screens/standing.dart'; import 'package:flutter/material.dart'; import 'package:capstone_hungry_hippos/screens/home_widget.dart'; import 'package:capstone_hungry_hippos/screens/sport.dart'; +import 'package:capstone_hungry_hippos/screens/twitter_widget.dart'; class RouteGenerator { static Route generateRoute(RouteSettings settings){ @@ -21,6 +22,8 @@ class RouteGenerator { return MaterialPageRoute(builder: (_) => Standing()); case '/Chat': return MaterialPageRoute(builder: (_) => Chat()); + case '/Twitter': + return MaterialPageRoute(builder: (_) => TwitterFeed()); default: return _errorRoute(); } diff --git a/lib/screens/home_widget.dart b/lib/screens/home_widget.dart index 6c0488d..fe40107 100644 --- a/lib/screens/home_widget.dart +++ b/lib/screens/home_widget.dart @@ -32,6 +32,12 @@ class Home extends StatelessWidget { onPressed: () => Navigator.pushNamed(context, '/Chat'), ), ), + ListTile( + title: IconButton( + icon: Icon(Icons.), + onPressed: () => Navigator.pushNamed(context, '/Twitter'), + ), + ), ], ), ), diff --git a/lib/screens/twitter_widget.dart b/lib/screens/twitter_widget.dart new file mode 100644 index 0000000..6fd8fa4 --- /dev/null +++ b/lib/screens/twitter_widget.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; + +class TwitterFeed extends StatelessWidget{ + @override + Widget build(BuildContext context) { + return StatefulBuilder( + builder: (context, StateSetter setState) => Scaffold( + appBar: AppBar( + centerTitle: false, + title: Text("49ers"), + backgroundColor: Colors.green, + ), + body: Text("Twitter Goes here"), + drawer: Drawer( + child: ListView( + children: [ + DrawerHeader( + child: Text( + 'Drawer Header', + style: TextStyle( + color: Colors.white, + fontSize: 24, + ), + ), + decoration: BoxDecoration( + color: Colors.green, + ), + ), + ListTile( + title: IconButton( + icon: Icon(Icons.home), + onPressed: () => Navigator.pushNamed(context, '/'), + ), + ), + ], + ), + ) + )); + } +} \ No newline at end of file From ddbbe8990336b77924c54efb822b3accd38578ac Mon Sep 17 00:00:00 2001 From: kconnel7 Date: Thu, 2 Apr 2020 19:08:29 -0400 Subject: [PATCH 04/17] Monthly Calendar w/ event placeholders & more detailed layout - No API --- lib/monthly_calendar.dart | 110 ++++++++++++++++++++++++++++++++------ lib/news/article.dart | 1 + 2 files changed, 94 insertions(+), 17 deletions(-) diff --git a/lib/monthly_calendar.dart b/lib/monthly_calendar.dart index 8de1bbf..53b5780 100644 --- a/lib/monthly_calendar.dart +++ b/lib/monthly_calendar.dart @@ -45,20 +45,20 @@ class _Calendar extends State with TickerProviderStateMixin { } void _DaySelected(DateTime day, List events) { - print('CALLBACK: _onDaySelected'); setState(() { _selectedEvents = events; }); } - void _onVisibleDaysChanged(DateTime first, DateTime last, CalendarFormat format) { + /*void _onVisibleDaysChanged(DateTime first, DateTime last, CalendarFormat format) { print('CALLBACK: _onVisibleDaysChanged'); } void _onCalendarCreated(DateTime first, DateTime last, CalendarFormat format) { print('CALLBACK: _onCalendarCreated'); - } + }*/ + //----- Builds calendar and event Lister ----- @override Widget build(BuildContext context) { return Center( @@ -66,12 +66,13 @@ class _Calendar extends State with TickerProviderStateMixin { children: [ _buildCalendar(), const SizedBox(height: 8.0), - Expanded(child: _buildEventList()), + Expanded(child: _eventLister()), ], ), ); } + //----- Builds calendar ----- @override Widget _buildCalendar() { return TableCalendar( @@ -87,7 +88,7 @@ class _Calendar extends State with TickerProviderStateMixin { calendarStyle: CalendarStyle( outsideWeekendStyle: TextStyle( - color: Colors.black, + color: Colors.grey, ), weekendStyle: TextStyle( @@ -98,7 +99,10 @@ class _Calendar extends State with TickerProviderStateMixin { daysOfWeekStyle: DaysOfWeekStyle( weekendStyle: TextStyle( color: Colors.black, - ) + ), + weekdayStyle: TextStyle( + color: Colors.black, + ), ), headerStyle: HeaderStyle( @@ -129,6 +133,7 @@ class _Calendar extends State with TickerProviderStateMixin { }, todayDayBuilder: (context, date, _) { + return Container( margin: const EdgeInsets.all(4.0), alignment: Alignment.center, @@ -142,7 +147,8 @@ class _Calendar extends State with TickerProviderStateMixin { child: Text( '${date.day}', - style: TextStyle(color: Color.fromRGBO(179, 163, 105, 1), //UNCC Gold + style: TextStyle( + color: Colors.black, ), ), ); @@ -160,9 +166,9 @@ class _Calendar extends State with TickerProviderStateMixin { ), ); } + return miniBox; }, - ), onDaySelected: (date, events) { @@ -170,8 +176,8 @@ class _Calendar extends State with TickerProviderStateMixin { _animationController.forward(from: 0.0); }, - onVisibleDaysChanged: _onVisibleDaysChanged, - onCalendarCreated: _onCalendarCreated, + //onVisibleDaysChanged: _onVisibleDaysChanged, + //onCalendarCreated: _onCalendarCreated, ); } @@ -183,9 +189,20 @@ class _Calendar extends State with TickerProviderStateMixin { decoration: BoxDecoration( shape: BoxShape.rectangle, - color: _calController.isSelected(date) + + /*border: _calController.isSelected(date) //if selected date + ? Border.all(color: Colors.black, width: 1.5,) + : _calController.isToday(date) //if today's date + ? Border.all(color: Colors.black, width: 1.5,) + : Border.all(color: Colors.black, width: 0,),*/ + + //color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green + //color: Colors.grey, + + color: _calController.isSelected(date) //if selected date ? Colors.blue[400] - : _calController.isToday(date) ? Colors.blue[400] : Color.fromRGBO(0, 112, 60, 1), + : Color.fromRGBO(0, 112, 60, 1), //UNCC Green + //: Colors.grey, ), width: 16.0, @@ -199,16 +216,44 @@ class _Calendar extends State with TickerProviderStateMixin { fontSize: 12.0, ), ), + ), + ); + } + //----- Format to Game Result ----- + Widget _buildGameResult() { + return Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green - if win + //color: Colors.grey, // - if lose/tie + ), + + width: 15.0, + height: 15.0, + alignment: Alignment.center, + + child: Text( + 'W', //Game Result (W-L-T) + style: TextStyle().copyWith( + color: Colors.white, // - if win + fontSize: 13.0, + fontWeight: FontWeight.bold, + + /*'L', //Game Result (W-L-T) + style: TextStyle().copyWith( + color: Colors.black, // - if lose/tie + fontSize: 13.0, + fontWeight: FontWeight.bold,*/ + ), ), ); } //----- Creates event display ----- - Widget _buildEventList() { + Widget _eventLister() { return ListView( - children: _selectedEvents - .map((event) => Container( + children: _selectedEvents.map((event) => Container( decoration: BoxDecoration( border: Border.all( @@ -219,14 +264,45 @@ class _Calendar extends State with TickerProviderStateMixin { borderRadius: BorderRadius.circular(12.0), ), + height: 70.0, margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0), child: ListTile( - title: Text(event.toString()), - onTap: () => print('$event tapped!'), + leading: Icon(Icons.accessible), //opponent logo + title: Row( + children: [ + //Text('vs. '), //home or away (vs. / @) + Text('at '), //home or away (vs. / at) + Text(event.toString()), + ], + ), + + //title: Text(event.toString()), + subtitle: Text('Sport'), + + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text('Score '), + _buildGameResult(), //Game Result (W-L) + //Text('TBD'), + + ], + ), + onTap: () => print('$event tapped!'), //When event display is clicked ), )) .toList(), ); } +} + +class TextScore { //Displays score of game + String team; + String opponent; + + TextScore({String this.team, String this.opponent}); + + @override + String toString() => team + " - " + opponent; } \ No newline at end of file diff --git a/lib/news/article.dart b/lib/news/article.dart index 4acc3a5..033f85b 100644 --- a/lib/news/article.dart +++ b/lib/news/article.dart @@ -76,6 +76,7 @@ class ArticleCard extends StatelessWidget { ], ); + return SizedBox( width: widthIn(context), child: Card( From b8b0a790f66e89014e81c6807b7b43f9e7773dbf Mon Sep 17 00:00:00 2001 From: kwainright Date: Tue, 7 Apr 2020 16:48:18 -0400 Subject: [PATCH 05/17] Twitter - Layout implemented - need to get API data --- lib/screens/home_widget.dart | 2 +- lib/screens/twitter_widget.dart | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/screens/home_widget.dart b/lib/screens/home_widget.dart index fe40107..cf8f09c 100644 --- a/lib/screens/home_widget.dart +++ b/lib/screens/home_widget.dart @@ -34,7 +34,7 @@ class Home extends StatelessWidget { ), ListTile( title: IconButton( - icon: Icon(Icons.), + icon: Icon(Icons.voice_chat), onPressed: () => Navigator.pushNamed(context, '/Twitter'), ), ), diff --git a/lib/screens/twitter_widget.dart b/lib/screens/twitter_widget.dart index 6fd8fa4..18807da 100644 --- a/lib/screens/twitter_widget.dart +++ b/lib/screens/twitter_widget.dart @@ -10,7 +10,21 @@ class TwitterFeed extends StatelessWidget{ title: Text("49ers"), backgroundColor: Colors.green, ), - body: Text("Twitter Goes here"), + body: Container( + color: Colors.black12, + child: ListView.builder( + itemCount: 10, + itemBuilder: (context, ind){ + return Card( + child: ListTile( + leading: FlutterLogo(), + title: Text('Twitter User'), + subtitle: Text('Tweet: I really hope I can figure out the whole URl thing what if this is longer and stuff. will it wrap around? I hope so we about to find out'), + ), + ); + } + ), + ), drawer: Drawer( child: ListView( children: [ @@ -37,4 +51,5 @@ class TwitterFeed extends StatelessWidget{ ) )); } -} \ No newline at end of file +} + From c8e0026a5163dc274e545efe99e2192e3a92691d Mon Sep 17 00:00:00 2001 From: kconnel7 Date: Wed, 8 Apr 2020 02:39:31 -0400 Subject: [PATCH 06/17] Monthly Calendar (API - Only Dates Work) --- lib/monthly_calendar.dart | 84 +++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 13 deletions(-) diff --git a/lib/monthly_calendar.dart b/lib/monthly_calendar.dart index 53b5780..875f001 100644 --- a/lib/monthly_calendar.dart +++ b/lib/monthly_calendar.dart @@ -1,6 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; import 'package:table_calendar/table_calendar.dart'; +import 'screens/sport_schedule.dart'; +import 'dart:convert'; + class Calendar extends StatefulWidget { @override _Calendar createState() => _Calendar(); @@ -12,21 +16,62 @@ class _Calendar extends State with TickerProviderStateMixin { AnimationController _animationController; CalendarController _calController; + //** ----- Fix so it can be any sport ----- ** + //static final sportUrl = 'https://charlotte49ers.com/services/adaptive_components.ashx?type=scoreboard&start=0&count=80'; + //Future> getEvents(int sportID) async { + + Future> getEvents() async { + //var url = '$sportUrl&sport_id=,$sportID&name=&extra=%7B%7D'; + var url = 'https://charlotte49ers.com/services/adaptive_components.ashx?type=scoreboard&start=0&count=80&sport_id=3&name=&extra=%7B%7D'; + + http.Response response = await http.get(url); + Iterable games = json.decode(response.body); + return games.map((e) => sport_schedule.fromJson(e)).toList(); + } + + Future> getGames() async { + Map mapGrab = {}; + + List eventInfo = await getEvents(); + + for (int i = 0; i < eventInfo.length; i++) { + var sportEvent = DateTime( + eventInfo[i].date.year, + eventInfo[i].date.month, + eventInfo[i].date.day + ); + var original = mapGrab[sportEvent]; + + if (original == null) { + //print("null"); + mapGrab[sportEvent] = [eventInfo[i].location]; + mapGrab[sportEvent] = [eventInfo[i].sportTitle]; + mapGrab[sportEvent] = [eventInfo[i].opponentTitle]; + mapGrab[sportEvent] = [eventInfo[i].status]; + mapGrab[sportEvent] = [eventInfo[i].team_score]; + mapGrab[sportEvent] = [eventInfo[i].opponent_score]; + } else { + //print(eventInfo[i].date); + mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].location]); + mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].sportTitle]); + mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].opponentTitle]); + mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].status]); + mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].team_score]); + mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].opponent_score]); + } + + print([eventInfo[i].location]); + } + + return mapGrab; + } + @override void initState() { - super.initState(); final _selectedDay = DateTime.now(); - _events = { - _selectedDay.add(Duration(days: 0)): ['Test'], - _selectedDay.add(Duration(days: 5)): ['Example 1'], - _selectedDay.add(Duration(days: 7)): ['Example 2'], - _selectedDay.add(Duration(days: 14)): ['Example 3'], - _selectedDay.add(Duration(days: 2)): ['Example 4'], - _selectedDay.add(Duration(days: 27)): ['Example 5'], - }; - - _selectedEvents = _events[_selectedDay] ?? []; + //_selectedEvents = _events[_selectedDay] ?? []; + _selectedEvents = []; _calController = CalendarController(); _animationController = AnimationController( @@ -35,6 +80,15 @@ class _Calendar extends State with TickerProviderStateMixin { ); _animationController.forward(); + + WidgetsBinding.instance.addPostFrameCallback((_) { + getGames().then((val) => setState(() { + _events = val; + })); + //print( ' ${_events.toString()} '); + }); + + super.initState(); } @override @@ -225,6 +279,7 @@ class _Calendar extends State with TickerProviderStateMixin { return Container( decoration: BoxDecoration( shape: BoxShape.rectangle, + color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green - if win //color: Colors.grey, // - if lose/tie ), @@ -253,6 +308,7 @@ class _Calendar extends State with TickerProviderStateMixin { //----- Creates event display ----- Widget _eventLister() { return ListView( + //children: [ children: _selectedEvents.map((event) => Container( decoration: BoxDecoration( @@ -273,12 +329,14 @@ class _Calendar extends State with TickerProviderStateMixin { children: [ //Text('vs. '), //home or away (vs. / @) Text('at '), //home or away (vs. / at) - Text(event.toString()), + Text('Opponent') + //Text(event.toString()), ], ), //title: Text(event.toString()), - subtitle: Text('Sport'), + //subtitle: Text('Sport '), + subtitle: Text('Sport - Location'), trailing: Row( mainAxisSize: MainAxisSize.min, From a2e2cb693d10a79d766681188e0a46c8bd9e09cc Mon Sep 17 00:00:00 2001 From: kwainright Date: Wed, 8 Apr 2020 19:17:24 -0400 Subject: [PATCH 07/17] Twitter - Api half way there - have to figure out the Twitter Authorization with Dart. --- lib/screens/twitter_widget.dart | 17 +++----- lib/twitter_assets/tweet.dart | 53 +++++++++++++++++++++++++ lib/twitter_assets/twitterFeed.dart | 60 +++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 12 deletions(-) create mode 100644 lib/twitter_assets/tweet.dart create mode 100644 lib/twitter_assets/twitterFeed.dart diff --git a/lib/screens/twitter_widget.dart b/lib/screens/twitter_widget.dart index 18807da..2a4a3b1 100644 --- a/lib/screens/twitter_widget.dart +++ b/lib/screens/twitter_widget.dart @@ -1,6 +1,10 @@ +import 'package:capstone_hungry_hippos/twitter_assets/twitterFeed.dart'; import 'package:flutter/material.dart'; +import '../twitter_assets/tweet.dart'; class TwitterFeed extends StatelessWidget{ + final feed = TwitterFeedCreation(); + @override Widget build(BuildContext context) { return StatefulBuilder( @@ -12,18 +16,7 @@ class TwitterFeed extends StatelessWidget{ ), body: Container( color: Colors.black12, - child: ListView.builder( - itemCount: 10, - itemBuilder: (context, ind){ - return Card( - child: ListTile( - leading: FlutterLogo(), - title: Text('Twitter User'), - subtitle: Text('Tweet: I really hope I can figure out the whole URl thing what if this is longer and stuff. will it wrap around? I hope so we about to find out'), - ), - ); - } - ), + child: VerticalTwitterFeed(twitterFeed: feed), ), drawer: Drawer( child: ListView( diff --git a/lib/twitter_assets/tweet.dart b/lib/twitter_assets/tweet.dart new file mode 100644 index 0000000..5c75f53 --- /dev/null +++ b/lib/twitter_assets/tweet.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; + +class Tweet { + final int id; + final String text; + final String userName; + final String userImgUrl; + final String url; + + Tweet( + this.id, { + this.text, + this.userName, + this.userImgUrl, + this.url, + }); + + factory Tweet.fromJson(Map json) { + return Tweet( + json['id_str'], + text: json['text'], + userName: json['user']['name'], + userImgUrl: json['user']['profile_image_url_https'], + url: json['urls']['expanded_url'], + ); + } +} + +class TwitterCard extends StatelessWidget{ + + const TwitterCard({ + Key key, + @required this.tweet, + }) : super(key: key); + + final Tweet tweet; + + @override + Widget build(BuildContext context) { + return Card( + child: ListTile( + leading: SizedBox( + width: 75, + height: 75, + child: Image.network('${tweet.userImgUrl}'), + ), + title: Text('${tweet.userName}'), + subtitle: Text('${tweet.text}'), + ), + ); + } +} + diff --git a/lib/twitter_assets/twitterFeed.dart b/lib/twitter_assets/twitterFeed.dart new file mode 100644 index 0000000..e0cab00 --- /dev/null +++ b/lib/twitter_assets/twitterFeed.dart @@ -0,0 +1,60 @@ +import 'dart:io'; + +import 'package:capstone_hungry_hippos/screens/twitter_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; + +import 'dart:convert'; + +import 'tweet.dart'; + +class TwitterFeedCreation { + static final twitterBase = 'https://api.twitter.com/1.1/search'; + + static final apiKey = 'AFBfOqx8uXIUBZMxAFoQyO3zA'; + static final apiSecret = '48Gp7nczz9SqExorwYuWpA6Nmviuox6Beq83kjH1XtYtunorym'; + + Future> getPage({int size = 10}) async { + var url = '$twitterBase/tweets.json?q=from%3ACharlotteFTBL&result_type=mixed&count=$size'; + http.Response response = await http.get(url + ); + Iterable tweets = json.decode(response.body); + return tweets.map((e) => Tweet.fromJson(e)).toList(); + } +} + + +class VerticalTwitterFeed extends StatelessWidget{ + + final TwitterFeedCreation twitterFeed; + + const VerticalTwitterFeed({ + Key key, + @required this.twitterFeed, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + child: FutureBuilder( + future: twitterFeed.getPage(), + builder: (ctx, snapshot){ + if(!snapshot.hasData){ + return Center(child: CircularProgressIndicator()); + }else{ + List tweets = snapshot.data; + return ListView.builder( + scrollDirection: Axis.vertical, + itemCount: tweets.length, + itemBuilder: (ctx, idx) { + return TwitterCard( + tweet: tweets[idx], + ); + }, + ); + } + }, + ), + ); + } +} \ No newline at end of file From 310248bf02efd35411a1bb9afed257707dcb54cd Mon Sep 17 00:00:00 2001 From: kconnel7 Date: Wed, 8 Apr 2020 23:35:43 -0400 Subject: [PATCH 08/17] Monthly Calendar - Switch case to handle ability to change sports as well as determine if sport needs gender switch --- images/male.png | Bin 19526 -> 21003 bytes lib/monthly_calendar.dart | 49 ++++++++----------------------- lib/screens/sport.dart | 60 +++++++++++++++++++++++++++++++++++++- pubspec.yaml | 6 +++- 4 files changed, 76 insertions(+), 39 deletions(-) diff --git a/images/male.png b/images/male.png index 5a518d860da9ebc8c32d85b39e259a619cbcad95..f39cd83b1ae830bba018fcb4138c258fd73146e4 100644 GIT binary patch literal 21003 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 b{~6Z`ufAb>TvZKtm?DFxtDnm{r-UW|_iJEu literal 19526 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 JWt~$(699EkbteD- diff --git a/lib/monthly_calendar.dart b/lib/monthly_calendar.dart index 875f001..d3cef7b 100644 --- a/lib/monthly_calendar.dart +++ b/lib/monthly_calendar.dart @@ -3,6 +3,7 @@ import 'package:http/http.dart' as http; import 'package:table_calendar/table_calendar.dart'; import 'screens/sport_schedule.dart'; +import 'screens/sport.dart' as globals; import 'dart:convert'; class Calendar extends StatefulWidget { @@ -16,13 +17,13 @@ class _Calendar extends State with TickerProviderStateMixin { AnimationController _animationController; CalendarController _calController; - //** ----- Fix so it can be any sport ----- ** - //static final sportUrl = 'https://charlotte49ers.com/services/adaptive_components.ashx?type=scoreboard&start=0&count=80'; - //Future> getEvents(int sportID) async { + int sportID = globals.Sport.sport_ID; + static final sportUrl = 'https://charlotte49ers.com/services/adaptive_components.ashx?type=scoreboard&start=0&count=80'; Future> getEvents() async { - //var url = '$sportUrl&sport_id=,$sportID&name=&extra=%7B%7D'; - var url = 'https://charlotte49ers.com/services/adaptive_components.ashx?type=scoreboard&start=0&count=80&sport_id=3&name=&extra=%7B%7D'; + var url = '$sportUrl&sport_id=$sportID&name=&extra=%7B%7D'; + + print(url); //temp http.Response response = await http.get(url); Iterable games = json.decode(response.body); @@ -44,25 +45,13 @@ class _Calendar extends State with TickerProviderStateMixin { if (original == null) { //print("null"); - mapGrab[sportEvent] = [eventInfo[i].location]; - mapGrab[sportEvent] = [eventInfo[i].sportTitle]; mapGrab[sportEvent] = [eventInfo[i].opponentTitle]; - mapGrab[sportEvent] = [eventInfo[i].status]; - mapGrab[sportEvent] = [eventInfo[i].team_score]; - mapGrab[sportEvent] = [eventInfo[i].opponent_score]; } else { //print(eventInfo[i].date); - mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].location]); - mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].sportTitle]); mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].opponentTitle]); - mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].status]); - mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].team_score]); - mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].opponent_score]); } - - print([eventInfo[i].location]); + //print([eventInfo[i].opponentTitle]); //temp } - return mapGrab; } @@ -85,7 +74,6 @@ class _Calendar extends State with TickerProviderStateMixin { getGames().then((val) => setState(() { _events = val; })); - //print( ' ${_events.toString()} '); }); super.initState(); @@ -308,7 +296,6 @@ class _Calendar extends State with TickerProviderStateMixin { //----- Creates event display ----- Widget _eventLister() { return ListView( - //children: [ children: _selectedEvents.map((event) => Container( decoration: BoxDecoration( @@ -324,18 +311,16 @@ class _Calendar extends State with TickerProviderStateMixin { margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0), child: ListTile( - leading: Icon(Icons.accessible), //opponent logo + leading: Icon(Icons.accessible), //opponent logo title: Row( children: [ - //Text('vs. '), //home or away (vs. / @) - Text('at '), //home or away (vs. / at) - Text('Opponent') - //Text(event.toString()), + //Text('vs. '), //home or away (vs. / @) + Text('at '), //home or away (vs. / at) + Text(event.toString()), //opponent name ], ), - //title: Text(event.toString()), - //subtitle: Text('Sport '), + //subtitle: Text(event.toString()), //Type of sport - Location subtitle: Text('Sport - Location'), trailing: Row( @@ -353,14 +338,4 @@ class _Calendar extends State with TickerProviderStateMixin { .toList(), ); } -} - -class TextScore { //Displays score of game - String team; - String opponent; - - TextScore({String this.team, String this.opponent}); - - @override - String toString() => team + " - " + opponent; } \ No newline at end of file diff --git a/lib/screens/sport.dart b/lib/screens/sport.dart index ac34014..3292f77 100644 --- a/lib/screens/sport.dart +++ b/lib/screens/sport.dart @@ -12,9 +12,14 @@ class Sport extends StatelessWidget { Item _curSport = colorList[0]; - final feed = Feed(); // was var not final + bool genderSportSwitch = false; + final String imageMale = 'images/male.png'; + final String imageFemale = 'images/female.png'; + + static int sport_ID; + @override Widget build(BuildContext context) { Item selectedSport; @@ -25,6 +30,28 @@ class Sport extends StatelessWidget { centerTitle: false, title: buildDropdownButton(selectedSport, setState), backgroundColor: _curSport.color, + + //--Gender Switch-- **Important; Need to make condition to determine gender + actions: [ + if (genderSportSwitch == true) + Switch( + value: false, + onChanged: (value) { + setState(() {}); + }, + inactiveThumbColor: Colors.lightBlue, + inactiveThumbImage: Image + .asset(imageMale) + .image, + + activeColor: Colors.pinkAccent, + activeThumbImage: Image + .asset(imageFemale) + .image, + ), + + ] + ), body: ListView( children: [ @@ -91,6 +118,37 @@ class Sport extends StatelessWidget { onChanged: (Item value) { setState(() { _curSport = value; + + //Will set the sport id / Display gender switch + switch (_curSport.name) { //prints are temporary + case 'FootBall': + print(_curSport.name); + print(genderSportSwitch); + genderSportSwitch = false; + sport_ID = 3; + break; + case 'BasketBall': + print(_curSport.name); + print(genderSportSwitch); + genderSportSwitch = true; + sport_ID = 5; //Male + //sport_ID = 13; //Female + break; + case 'Soccer': + print(_curSport.name); + print(genderSportSwitch); + genderSportSwitch = true; + sport_ID = 9; //Male + //sport_ID = 17; //Female + break; + case 'Baseball': + print(_curSport.name); + print(genderSportSwitch); + genderSportSwitch = false; + sport_ID = 1; + break; + } + print(sport_ID); }); }, items: colorList.map>((Item item) { diff --git a/pubspec.yaml b/pubspec.yaml index 3667529..e100b59 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,8 @@ description: A sports app for UNC-Charlotte 49ers version: 1.0.0+1 environment: - sdk: ">=2.1.0 <3.0.0" + #sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.5.2 <3.0.0" dependencies: flutter: @@ -48,6 +49,9 @@ flutter: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg + assets: + - images/male.png + - images/female.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. From e9a8abfe00b59436230df7a4f2c819806e046572 Mon Sep 17 00:00:00 2001 From: kconnel7 Date: Thu, 9 Apr 2020 05:51:59 -0400 Subject: [PATCH 09/17] Monthly Calendar - Multiple Objects displayed from API (All that remains are home/away marker colors, status/scores, opponent logos, and having gender switch work to change displayed games from either gender) --- lib/monthly_calendar.dart | 157 +++++++++++++++++++++++++------------- lib/screens/sport.dart | 63 ++++++++++----- 2 files changed, 145 insertions(+), 75 deletions(-) diff --git a/lib/monthly_calendar.dart b/lib/monthly_calendar.dart index d3cef7b..bf1efc4 100644 --- a/lib/monthly_calendar.dart +++ b/lib/monthly_calendar.dart @@ -11,9 +11,11 @@ class Calendar extends StatefulWidget { _Calendar createState() => _Calendar(); } +List _selectedEvents; +DateTime selectedDay; +Map> _events; + class _Calendar extends State with TickerProviderStateMixin { - Map _events; - List _selectedEvents; AnimationController _animationController; CalendarController _calController; @@ -23,15 +25,17 @@ class _Calendar extends State with TickerProviderStateMixin { Future> getEvents() async { var url = '$sportUrl&sport_id=$sportID&name=&extra=%7B%7D'; - print(url); //temp + //print(url); //temp http.Response response = await http.get(url); Iterable games = json.decode(response.body); - return games.map((e) => sport_schedule.fromJson(e)).toList(); + + return games.map((json) => sport_schedule.fromJson(json)).toList(); + //return games.map((e) => sport_schedule.fromJson(e)).toList(); } - Future> getGames() async { - Map mapGrab = {}; + Future>> getGames() async { + Map> mapGrab = {}; List eventInfo = await getEvents(); @@ -45,10 +49,10 @@ class _Calendar extends State with TickerProviderStateMixin { if (original == null) { //print("null"); - mapGrab[sportEvent] = [eventInfo[i].opponentTitle]; + mapGrab[sportEvent] = [eventInfo[i]]; } else { //print(eventInfo[i].date); - mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i].opponentTitle]); + mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i]]); } //print([eventInfo[i].opponentTitle]); //temp } @@ -86,9 +90,10 @@ class _Calendar extends State with TickerProviderStateMixin { super.dispose(); } - void _DaySelected(DateTime day, List events) { + void _DaySelected(DateTime day, List events) { setState(() { _selectedEvents = events; + selectedDay = DateTime(day.year, day.month, day.day); }); } @@ -226,7 +231,7 @@ class _Calendar extends State with TickerProviderStateMixin { //----- Creates event box display (mini box) ----- Widget _buildEventsMarker(DateTime date, List events) { - return AnimatedContainer( + children: _selectedEvents.map((event) => AnimatedContainer( duration: const Duration(milliseconds: 300), decoration: BoxDecoration( @@ -259,45 +264,13 @@ class _Calendar extends State with TickerProviderStateMixin { ), ), ), - ); - } - - //----- Format to Game Result ----- - Widget _buildGameResult() { - return Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - - color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green - if win - //color: Colors.grey, // - if lose/tie - ), - - width: 15.0, - height: 15.0, - alignment: Alignment.center, - - child: Text( - 'W', //Game Result (W-L-T) - style: TextStyle().copyWith( - color: Colors.white, // - if win - fontSize: 13.0, - fontWeight: FontWeight.bold, - - /*'L', //Game Result (W-L-T) - style: TextStyle().copyWith( - color: Colors.black, // - if lose/tie - fontSize: 13.0, - fontWeight: FontWeight.bold,*/ - ), - ), - ); + )); } //----- Creates event display ----- Widget _eventLister() { return ListView( children: _selectedEvents.map((event) => Container( - decoration: BoxDecoration( border: Border.all( color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green @@ -311,31 +284,107 @@ class _Calendar extends State with TickerProviderStateMixin { margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0), child: ListTile( - leading: Icon(Icons.accessible), //opponent logo + leading: Icon(Icons.accessible), //opponent logo - Not done title: Row( children: [ - //Text('vs. '), //home or away (vs. / @) - Text('at '), //home or away (vs. / at) - Text(event.toString()), //opponent name + if (event.location.toString() == "Charlotte, NC" || event.location.toString() == "Charlotte, N.C.") + Text('vs. ') //home game + else + Text('at '), //away game + + Text(event.opponentTitle.toString()), //opponent name ], ), - //subtitle: Text(event.toString()), //Type of sport - Location - subtitle: Text('Sport - Location'), + subtitle: Text(event.sportTitle.toString() + " - " + event.location.toString()), //Type of sport - Location trailing: Row( mainAxisSize: MainAxisSize.min, children: [ - Text('Score '), - _buildGameResult(), //Game Result (W-L) - //Text('TBD'), + //Game Result (W/L/T) - Not done + /*if (event.status.toString() == "W") + _buildGameResultWin() + else if (event.status.toString() == "L") + _buildGameResultLose() + else if (event.status.toString() == "T") + _buildGameResultTie() + else + Text('TBD')*/ ], ), onTap: () => print('$event tapped!'), //When event display is clicked ), - )) - .toList(), + )).toList(), ); } + + //----- Format to Game Result (W)----- + Widget _buildGameResultWin() { + children: _selectedEvents.map((event) => Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Color.fromRGBO(0, 112, 60, 1), + ), + + width: 15.0, + height: 15.0, + alignment: Alignment.center, + + child: Text( + event.status.toString(), //Game Result (W-L-T) + style: TextStyle().copyWith( + color: Colors.white, + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), + ), + )); + } + + //----- Format to Game Result (L)----- + Widget _buildGameResultLose() { + children: _selectedEvents.map((event) => Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Colors.grey, + ), + + width: 15.0, + height: 15.0, + alignment: Alignment.center, + + child: Text( + event.status.toString(), //Game Result (W-L-T) + style: TextStyle().copyWith( + color: Colors.black, + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), + ), + )); + } + + //----- Format to Game Result (T)----- + Widget _buildGameResultTie() { + children: _selectedEvents.map((event) => Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Colors.grey, + ), + + width: 15.0, + height: 15.0, + alignment: Alignment.center, + + child: Text( + event.status.toString(), //Game Result (W-L-T) + style: TextStyle().copyWith( + color: Colors.black, + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), + ), + )); + } } \ No newline at end of file diff --git a/lib/screens/sport.dart b/lib/screens/sport.dart index 3292f77..ec3b377 100644 --- a/lib/screens/sport.dart +++ b/lib/screens/sport.dart @@ -14,9 +14,10 @@ class Sport extends StatelessWidget { final feed = Feed(); // was var not final - bool genderSportSwitch = false; + bool genderSportSwitch = false; //determines if sport needs the gender switch final String imageMale = 'images/male.png'; final String imageFemale = 'images/female.png'; + bool genderSport = false; //determines which gender switch is set M - false / F - True static int sport_ID; @@ -37,17 +38,22 @@ class Sport extends StatelessWidget { Switch( value: false, onChanged: (value) { - setState(() {}); + setState(() { + if (value == false) { + genderSport = false; + } + else { + genderSport = true; + } + + //print(genderSport); + }); }, inactiveThumbColor: Colors.lightBlue, - inactiveThumbImage: Image - .asset(imageMale) - .image, + inactiveThumbImage: Image.asset(imageMale).image, activeColor: Colors.pinkAccent, - activeThumbImage: Image - .asset(imageFemale) - .image, + activeThumbImage: Image.asset(imageFemale).image, ), ] @@ -120,31 +126,46 @@ class Sport extends StatelessWidget { _curSport = value; //Will set the sport id / Display gender switch - switch (_curSport.name) { //prints are temporary + switch (_curSport.name) { //prints are temp case 'FootBall': - print(_curSport.name); - print(genderSportSwitch); + //print(_curSport.name); genderSportSwitch = false; + //print(genderSportSwitch); + sport_ID = 3; break; + case 'BasketBall': - print(_curSport.name); - print(genderSportSwitch); + //print(_curSport.name); genderSportSwitch = true; - sport_ID = 5; //Male - //sport_ID = 13; //Female + //print(genderSportSwitch); + + if (genderSport == false) { + sport_ID = 5; //Male + } + else { + sport_ID = 13; //Female + } break; + case 'Soccer': - print(_curSport.name); - print(genderSportSwitch); + //print(_curSport.name); genderSportSwitch = true; - sport_ID = 9; //Male - //sport_ID = 17; //Female + //print(genderSportSwitch); + + if (genderSport == false) { + sport_ID = 9; //Male + } + else { + sport_ID = 17; //Female + } break; + case 'Baseball': - print(_curSport.name); - print(genderSportSwitch); + //print(_curSport.name); genderSportSwitch = false; + //print(genderSportSwitch); + sport_ID = 1; break; } From 9fc50a5215416c05bc5f7f5a419d2b541225ed0e Mon Sep 17 00:00:00 2001 From: kwainright Date: Thu, 9 Apr 2020 17:50:51 -0400 Subject: [PATCH 10/17] Twitter - Api half way there - committing to check out other branch --- lib/twitter_assets/twitterFeed.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/twitter_assets/twitterFeed.dart b/lib/twitter_assets/twitterFeed.dart index e0cab00..9199593 100644 --- a/lib/twitter_assets/twitterFeed.dart +++ b/lib/twitter_assets/twitterFeed.dart @@ -14,9 +14,14 @@ class TwitterFeedCreation { static final apiKey = 'AFBfOqx8uXIUBZMxAFoQyO3zA'; static final apiSecret = '48Gp7nczz9SqExorwYuWpA6Nmviuox6Beq83kjH1XtYtunorym'; + getToken() async { + http.Response response = await http.get('https://api.twitter.com/oauth2/token',); +} + Future> getPage({int size = 10}) async { var url = '$twitterBase/tweets.json?q=from%3ACharlotteFTBL&result_type=mixed&count=$size'; - http.Response response = await http.get(url + http.Response response = await http.get(url, + headers: {} ); Iterable tweets = json.decode(response.body); return tweets.map((e) => Tweet.fromJson(e)).toList(); From 2d103cba78e0a185445af32557338ebfbee32fe0 Mon Sep 17 00:00:00 2001 From: kwainright Date: Thu, 9 Apr 2020 18:32:06 -0400 Subject: [PATCH 11/17] Twitter - Api half way there - committing to check out other branch --- lib/twitter_assets/twitterFeed.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/twitter_assets/twitterFeed.dart b/lib/twitter_assets/twitterFeed.dart index 9199593..90fc5cd 100644 --- a/lib/twitter_assets/twitterFeed.dart +++ b/lib/twitter_assets/twitterFeed.dart @@ -21,7 +21,7 @@ class TwitterFeedCreation { Future> getPage({int size = 10}) async { var url = '$twitterBase/tweets.json?q=from%3ACharlotteFTBL&result_type=mixed&count=$size'; http.Response response = await http.get(url, - headers: {} + headers: {'authorization': apiKey,} ); Iterable tweets = json.decode(response.body); return tweets.map((e) => Tweet.fromJson(e)).toList(); From 0510b9f7dddb69ae52a6d0a615ee0cf1e1423e7d Mon Sep 17 00:00:00 2001 From: kwainright Date: Thu, 9 Apr 2020 20:38:48 -0400 Subject: [PATCH 12/17] Twitter - proof of concept - needs api fleshed out. has place holder data --- lib/screens/twitter_widget.dart | 23 +++++++++++++++--- lib/twitter_assets/tweet.dart | 36 +++++++++++++++++++++-------- lib/twitter_assets/twitterFeed.dart | 21 +++++++++++++---- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/lib/screens/twitter_widget.dart b/lib/screens/twitter_widget.dart index 2a4a3b1..593cb73 100644 --- a/lib/screens/twitter_widget.dart +++ b/lib/screens/twitter_widget.dart @@ -3,20 +3,37 @@ import 'package:flutter/material.dart'; import '../twitter_assets/tweet.dart'; class TwitterFeed extends StatelessWidget{ - final feed = TwitterFeedCreation(); + List fuck = []; + final test = new Tweet(1, "We'll get through this together, Niner Nation. #WeAreAllNiners", "@unccharlotte", "https://pbs.twimg.com/profile_images/1175214096280629249/QC79Xju2_400x400.jpg", "test"); + final test2 = new Tweet(2, "Let's test your UNC Charlotte knowledge...do you know why we became the 49ers? Here's the full history on the pioneering spirit that shaped our trajectory http://bit.ly/UNCC-1949", "@unccharlotte", "https://pbs.twimg.com/profile_images/1175214096280629249/QC79Xju2_400x400.jpg", "test"); + final test3 = new Tweet(3, "Niner Nation means uplifting each other. This 4/9 Day, let's show our students why #WeAreAllNiners by supporting the Student Emergency Relief Fund ️ http://bit.ly/UNCC-SER", "@unccharlotte", "https://pbs.twimg.com/profile_images/1175214096280629249/QC79Xju2_400x400.jpg", "test"); + final test4 = new Tweet(4, "Niner Nation: Chancellor Dubois shares that UNC Charlotte will be able to apply our established parking refund procedures with special considerations for the impact of COVID-19.", "@unccharlotte", "https://pbs.twimg.com/profile_images/1175214096280629249/QC79Xju2_400x400.jpg", "test"); + final test5 = new Tweet(5, "4/9 Day is just for us, Niner Nation. From wherever you are, you're family #WeAreAllNiners", "@unccharlotte", "https://pbs.twimg.com/profile_images/1175214096280629249/QC79Xju2_400x400.jpg", "test"); + final test6= new Tweet(6, "Niner Nation, #49erAlumni Gene Johnson ’73 is getting us excited for 4/9 Day tomorrow! Put on your Niner gear, call your friends and let’s celebrate together virtually \n We’re all in this together! ", "@unccharlotte", "https://pbs.twimg.com/profile_images/1175214096280629249/QC79Xju2_400x400.jpg", "test"); + final test7 = new Tweet(7, "From virtual events to one-on-one sessions with counselors, it's easy to stay connected with @UNCCAdmissions", "@unccharlotte", "https://pbs.twimg.com/profile_images/1175214096280629249/QC79Xju2_400x400.jpg", "test"); + @override Widget build(BuildContext context) { + fuck.add(test); + fuck.add(test2); + fuck.add(test3); + fuck.add(test4); + fuck.add(test5); + fuck.add(test6); + fuck.add(test7); + return StatefulBuilder( builder: (context, StateSetter setState) => Scaffold( appBar: AppBar( centerTitle: false, - title: Text("49ers"), + title: Text("49ers Tweets"), backgroundColor: Colors.green, ), body: Container( color: Colors.black12, - child: VerticalTwitterFeed(twitterFeed: feed), + child: + VerticalTwitterFeed(twitterFeed: fuck), ), drawer: Drawer( child: ListView( diff --git a/lib/twitter_assets/tweet.dart b/lib/twitter_assets/tweet.dart index 5c75f53..47aac31 100644 --- a/lib/twitter_assets/tweet.dart +++ b/lib/twitter_assets/tweet.dart @@ -8,14 +8,14 @@ class Tweet { final String url; Tweet( - this.id, { + this.id, this.text, this.userName, this.userImgUrl, this.url, - }); + ); - factory Tweet.fromJson(Map json) { + /*factory Tweet.fromJson(Map json) { return Tweet( json['id_str'], text: json['text'], @@ -24,6 +24,11 @@ class Tweet { url: json['urls']['expanded_url'], ); } + Commenting out till we figure out the API + */ + + + } class TwitterCard extends StatelessWidget{ @@ -38,14 +43,25 @@ class TwitterCard extends StatelessWidget{ @override Widget build(BuildContext context) { return Card( - child: ListTile( - leading: SizedBox( - width: 75, - height: 75, - child: Image.network('${tweet.userImgUrl}'), + child: Padding( + padding: EdgeInsets.symmetric(vertical: 10, horizontal: 0), + child: ListTile( + leading: SizedBox( + height: 125, + width: 75, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + fit: BoxFit.fill, + image: NetworkImage('${tweet.userImgUrl}'), + ), + ), + ), + ), + title: Text('${tweet.userName}'), + subtitle: Text('${tweet.text}'), ), - title: Text('${tweet.userName}'), - subtitle: Text('${tweet.text}'), ), ); } diff --git a/lib/twitter_assets/twitterFeed.dart b/lib/twitter_assets/twitterFeed.dart index 90fc5cd..4fdc735 100644 --- a/lib/twitter_assets/twitterFeed.dart +++ b/lib/twitter_assets/twitterFeed.dart @@ -18,20 +18,20 @@ class TwitterFeedCreation { http.Response response = await http.get('https://api.twitter.com/oauth2/token',); } - Future> getPage({int size = 10}) async { + /*Future> getPage({int size = 10}) async { var url = '$twitterBase/tweets.json?q=from%3ACharlotteFTBL&result_type=mixed&count=$size'; http.Response response = await http.get(url, headers: {'authorization': apiKey,} ); Iterable tweets = json.decode(response.body); return tweets.map((e) => Tweet.fromJson(e)).toList(); - } + } */ } class VerticalTwitterFeed extends StatelessWidget{ - final TwitterFeedCreation twitterFeed; + final List twitterFeed; const VerticalTwitterFeed({ Key key, @@ -40,7 +40,20 @@ class VerticalTwitterFeed extends StatelessWidget{ @override Widget build(BuildContext context) { + return Container( + child: ListView.builder( + scrollDirection: Axis.vertical, + itemCount: twitterFeed.length, + itemBuilder: (ctx, idx){ + return TwitterCard( + tweet: twitterFeed[idx], + ); + }, + ), + ); + + /* return Container( child: FutureBuilder( future: twitterFeed.getPage(), builder: (ctx, snapshot){ @@ -60,6 +73,6 @@ class VerticalTwitterFeed extends StatelessWidget{ } }, ), - ); + ); */ } } \ No newline at end of file From 71c0c072ab023829895750d6a85116256ce62713 Mon Sep 17 00:00:00 2001 From: kwainright Date: Thu, 9 Apr 2020 20:44:14 -0400 Subject: [PATCH 13/17] Twitter - proof of concept - needs api fleshed out. has place holder data - edited the images --- lib/twitter_assets/tweet.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/twitter_assets/tweet.dart b/lib/twitter_assets/tweet.dart index 47aac31..31b571c 100644 --- a/lib/twitter_assets/tweet.dart +++ b/lib/twitter_assets/tweet.dart @@ -47,7 +47,7 @@ class TwitterCard extends StatelessWidget{ padding: EdgeInsets.symmetric(vertical: 10, horizontal: 0), child: ListTile( leading: SizedBox( - height: 125, + height: 150, width: 75, child: Container( decoration: BoxDecoration( From 8dd5979758f85b5cab6644bb59999f4a52bf2910 Mon Sep 17 00:00:00 2001 From: kconnel7 Date: Fri, 10 Apr 2020 12:16:20 -0400 Subject: [PATCH 14/17] Monthly Calendar - Showcases Scores and game status; status has formatting. What remains; Home/Away Marker Colors, Gender Switch to switch between genders, display opponent logos. (Will be Phase 3) --- lib/monthly_calendar.dart | 230 +++++++++++++++++++------------------- lib/news/feed.dart | 7 ++ lib/screens/sport.dart | 22 ++-- 3 files changed, 126 insertions(+), 133 deletions(-) diff --git a/lib/monthly_calendar.dart b/lib/monthly_calendar.dart index bf1efc4..8730ac6 100644 --- a/lib/monthly_calendar.dart +++ b/lib/monthly_calendar.dart @@ -11,7 +11,8 @@ class Calendar extends StatefulWidget { _Calendar createState() => _Calendar(); } -List _selectedEvents; +//List _selectedEvents; //original that makes events work +List _selectedEvents; //Removing the allows it to still work. Proceed with caution DateTime selectedDay; Map> _events; @@ -25,8 +26,6 @@ class _Calendar extends State with TickerProviderStateMixin { Future> getEvents() async { var url = '$sportUrl&sport_id=$sportID&name=&extra=%7B%7D'; - //print(url); //temp - http.Response response = await http.get(url); Iterable games = json.decode(response.body); @@ -54,7 +53,6 @@ class _Calendar extends State with TickerProviderStateMixin { //print(eventInfo[i].date); mapGrab[sportEvent] = List.from(original)..addAll([eventInfo[i]]); } - //print([eventInfo[i].opponentTitle]); //temp } return mapGrab; } @@ -90,7 +88,8 @@ class _Calendar extends State with TickerProviderStateMixin { super.dispose(); } - void _DaySelected(DateTime day, List events) { + //void _DaySelected(DateTime day, List events) { //original that makes events work + void _DaySelected(DateTime day, List events) { //Removing the allows it to still work. Proceed with caution setState(() { _selectedEvents = events; selectedDay = DateTime(day.year, day.month, day.day); @@ -100,7 +99,6 @@ class _Calendar extends State with TickerProviderStateMixin { /*void _onVisibleDaysChanged(DateTime first, DateTime last, CalendarFormat format) { print('CALLBACK: _onVisibleDaysChanged'); } - void _onCalendarCreated(DateTime first, DateTime last, CalendarFormat format) { print('CALLBACK: _onCalendarCreated'); }*/ @@ -144,12 +142,12 @@ class _Calendar extends State with TickerProviderStateMixin { ), daysOfWeekStyle: DaysOfWeekStyle( - weekendStyle: TextStyle( - color: Colors.black, - ), - weekdayStyle: TextStyle( - color: Colors.black, - ), + weekendStyle: TextStyle( + color: Colors.black, + ), + weekdayStyle: TextStyle( + color: Colors.black, + ), ), headerStyle: HeaderStyle( @@ -182,22 +180,22 @@ class _Calendar extends State with TickerProviderStateMixin { todayDayBuilder: (context, date, _) { return Container( - margin: const EdgeInsets.all(4.0), - alignment: Alignment.center, + margin: const EdgeInsets.all(4.0), + alignment: Alignment.center, - decoration: BoxDecoration( - border: Border.all( - color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green - ), - borderRadius: BorderRadius.circular(10.0) - ), - - child: Text( - '${date.day}', - style: TextStyle( - color: Colors.black, + decoration: BoxDecoration( + border: Border.all( + color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green ), + borderRadius: BorderRadius.circular(10.0) + ), + + child: Text( + '${date.day}', + style: TextStyle( + color: Colors.black, ), + ), ); }, @@ -231,7 +229,7 @@ class _Calendar extends State with TickerProviderStateMixin { //----- Creates event box display (mini box) ----- Widget _buildEventsMarker(DateTime date, List events) { - children: _selectedEvents.map((event) => AnimatedContainer( + return AnimatedContainer( duration: const Duration(milliseconds: 300), decoration: BoxDecoration( @@ -246,10 +244,11 @@ class _Calendar extends State with TickerProviderStateMixin { //color: Color.fromRGBO(0, 112, 60, 1), //UNCC Green //color: Colors.grey, - color: _calController.isSelected(date) //if selected date + //if selected date && home game / else away game + color: _calController.isSelected(date) ? Colors.blue[400] : Color.fromRGBO(0, 112, 60, 1), //UNCC Green - //: Colors.grey, + //: Colors.grey, ), width: 16.0, @@ -264,7 +263,7 @@ class _Calendar extends State with TickerProviderStateMixin { ), ), ), - )); + ); } //----- Creates event display ----- @@ -284,32 +283,96 @@ class _Calendar extends State with TickerProviderStateMixin { margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0), child: ListTile( - leading: Icon(Icons.accessible), //opponent logo - Not done - title: Row( - children: [ - if (event.location.toString() == "Charlotte, NC" || event.location.toString() == "Charlotte, N.C.") - Text('vs. ') //home game - else - Text('at '), //away game + leading: Icon(Icons.image), //opponent logo - Not done (Placeholder) + title: Wrap( - Text(event.opponentTitle.toString()), //opponent name + + children: [ + if (event.location_indicator.toString() == "H") + Text( + 'vs. ', + style: TextStyle( //home game + fontSize: 11.6, + ), + ) + else + Text( + 'at ', + style: TextStyle( //away game + fontSize: 11.6, + ), + ), + + Text( + event.opponentTitle.toString(), + style: TextStyle( + fontSize: 11.6, + ), + ) //opponent name ], ), - subtitle: Text(event.sportTitle.toString() + " - " + event.location.toString()), //Type of sport - Location + //Type of sport - Location + subtitle: Text( + event.sportTitle.toString() + " - " + event.location.toString(), + style: TextStyle( + fontSize: 10.3, + ), + ), + + trailing: Wrap( + //mainAxisSize: MainAxisSize.min, - trailing: Row( - mainAxisSize: MainAxisSize.min, children: [ - //Game Result (W/L/T) - Not done - /*if (event.status.toString() == "W") - _buildGameResultWin() - else if (event.status.toString() == "L") - _buildGameResultLose() - else if (event.status.toString() == "T") - _buildGameResultTie() - else - Text('TBD')*/ + //---Score--- + //Game hasn't occured + if (event.status.toString() == "null") + Text("TBD"), + + //---Scores--- + if (event.status.toString() == "W" || event.status.toString() == "L" || event.status.toString() == "T") //Finished games + Text(event.team_score.toString() + " - " + event.opponent_score.toString() + " ") + + else if (event.status.toString() == "N" && event.team_score.toString() != "null" && event.opponent_score.toString() != "null") //Games that don't count + Text(event.team_score.toString() + " - " + event.opponent_score.toString() + " "), + + //---Game Status--- + if (event.status.toString() == "W") //Win + Text( + (" " + event.status.toString() + " "), + style: TextStyle( + color: Colors.white, + backgroundColor: Color.fromRGBO(0, 112, 60, 1), + ) + ), + + if (event.status.toString() == "L" || event.status.toString() == "T") //Lose-Tie + Text( + (" " + event.status.toString() + " "), + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + backgroundColor: Colors.grey, + ) + ), + + if (event.status.toString() == "N" && event.postscore.toString() != "Canceled") //N + Text( + (" " + event.status.toString() + " "), + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + backgroundColor: Colors.grey, + ) + ) + else if (event.team_score.toString() == "null" && event.opponent_score.toString() == "null" + && event.status.toString() == "N") //Game was canceled + Text( + "Canceled", + style: TextStyle( + color: Colors.red, + ) + ), ], ), @@ -318,73 +381,4 @@ class _Calendar extends State with TickerProviderStateMixin { )).toList(), ); } - - //----- Format to Game Result (W)----- - Widget _buildGameResultWin() { - children: _selectedEvents.map((event) => Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Color.fromRGBO(0, 112, 60, 1), - ), - - width: 15.0, - height: 15.0, - alignment: Alignment.center, - - child: Text( - event.status.toString(), //Game Result (W-L-T) - style: TextStyle().copyWith( - color: Colors.white, - fontSize: 13.0, - fontWeight: FontWeight.bold, - ), - ), - )); - } - - //----- Format to Game Result (L)----- - Widget _buildGameResultLose() { - children: _selectedEvents.map((event) => Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Colors.grey, - ), - - width: 15.0, - height: 15.0, - alignment: Alignment.center, - - child: Text( - event.status.toString(), //Game Result (W-L-T) - style: TextStyle().copyWith( - color: Colors.black, - fontSize: 13.0, - fontWeight: FontWeight.bold, - ), - ), - )); - } - - //----- Format to Game Result (T)----- - Widget _buildGameResultTie() { - children: _selectedEvents.map((event) => Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - color: Colors.grey, - ), - - width: 15.0, - height: 15.0, - alignment: Alignment.center, - - child: Text( - event.status.toString(), //Game Result (W-L-T) - style: TextStyle().copyWith( - color: Colors.black, - fontSize: 13.0, - fontWeight: FontWeight.bold, - ), - ), - )); - } } \ No newline at end of file diff --git a/lib/news/feed.dart b/lib/news/feed.dart index f9da8d6..c5662ce 100644 --- a/lib/news/feed.dart +++ b/lib/news/feed.dart @@ -43,7 +43,14 @@ class HorizontalNewsFeed extends StatelessWidget { title: title, trailing: IconButton( icon: Icon(Icons.navigate_next), + onPressed: () => Navigator.of(context).pushNamed('/Sport'), + + /*onPressed: () { //changed + Navigator.of(context).pushNamed('/Sport'); + print(Navigator.of(context).pushNamed('/Sport')); + }*/ + ), ), Expanded( diff --git a/lib/screens/sport.dart b/lib/screens/sport.dart index ec3b377..b141d4d 100644 --- a/lib/screens/sport.dart +++ b/lib/screens/sport.dart @@ -17,7 +17,7 @@ class Sport extends StatelessWidget { bool genderSportSwitch = false; //determines if sport needs the gender switch final String imageMale = 'images/male.png'; final String imageFemale = 'images/female.png'; - bool genderSport = false; //determines which gender switch is set M - false / F - True + static bool genderSport = false; //determines which gender switch is set M - false / F - True static int sport_ID; @@ -32,11 +32,11 @@ class Sport extends StatelessWidget { title: buildDropdownButton(selectedSport, setState), backgroundColor: _curSport.color, - //--Gender Switch-- **Important; Need to make condition to determine gender + //--Gender Switch-- Need to make condition to determine gender actions: [ if (genderSportSwitch == true) Switch( - value: false, + value: genderSport, onChanged: (value) { setState(() { if (value == false) { @@ -46,7 +46,8 @@ class Sport extends StatelessWidget { genderSport = true; } - //print(genderSport); + print("value: " + value.toString()); + print("gender: " + genderSport.toString()); }); }, inactiveThumbColor: Colors.lightBlue, @@ -55,9 +56,7 @@ class Sport extends StatelessWidget { activeColor: Colors.pinkAccent, activeThumbImage: Image.asset(imageFemale).image, ), - ] - ), body: ListView( children: [ @@ -125,20 +124,17 @@ class Sport extends StatelessWidget { setState(() { _curSport = value; + print("genderSport: " + genderSport.toString()); + //Will set the sport id / Display gender switch switch (_curSport.name) { //prints are temp case 'FootBall': - //print(_curSport.name); genderSportSwitch = false; - //print(genderSportSwitch); - sport_ID = 3; break; case 'BasketBall': - //print(_curSport.name); genderSportSwitch = true; - //print(genderSportSwitch); if (genderSport == false) { sport_ID = 5; //Male @@ -149,9 +145,7 @@ class Sport extends StatelessWidget { break; case 'Soccer': - //print(_curSport.name); genderSportSwitch = true; - //print(genderSportSwitch); if (genderSport == false) { sport_ID = 9; //Male @@ -162,9 +156,7 @@ class Sport extends StatelessWidget { break; case 'Baseball': - //print(_curSport.name); genderSportSwitch = false; - //print(genderSportSwitch); sport_ID = 1; break; From 0bf3de6916cc8133ec36162735a8cc0a69bcc66d Mon Sep 17 00:00:00 2001 From: Carlos Lopez-Rosario Date: Fri, 10 Apr 2020 13:30:50 -0400 Subject: [PATCH 15/17] Added missing import --- lib/route_generator.dart | 1 + pubspec.lock | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/lib/route_generator.dart b/lib/route_generator.dart index d6f5ba9..ac14084 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:capstone_hungry_hippos/screens/home_widget.dart'; import 'package:capstone_hungry_hippos/screens/sport.dart'; import 'package:capstone_hungry_hippos/screens/twitter_widget.dart'; +import 'package:capstone_hungry_hippos/screens/favorites_reorder.dart'; class RouteGenerator { static Route generateRoute(RouteSettings settings) { diff --git a/pubspec.lock b/pubspec.lock index 764cf68..3e6efa1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,21 +7,21 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "2.0.11" + version: "2.0.13" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.5.2" + version: "1.6.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "2.4.1" bloc: dependency: transitive description: @@ -35,21 +35,21 @@ packages: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "2.0.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.1.3" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" + version: "1.14.12" convert: dependency: transitive description: @@ -63,7 +63,7 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "2.1.4" cupertino_icons: dependency: "direct main" description: @@ -113,7 +113,7 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.12" matcher: dependency: transitive description: @@ -169,7 +169,7 @@ packages: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.1.3" rxdart: dependency: transitive description: @@ -216,7 +216,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.7.0" stack_trace: dependency: transitive description: @@ -251,7 +251,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.11" + version: "0.2.15" typed_data: dependency: transitive description: @@ -272,7 +272,7 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.5.0" + version: "3.6.1" sdks: dart: ">=2.6.0 <3.0.0" flutter: ">=1.12.13+hotfix.4 <2.0.0" From 287998bdf79e158a01c80bd5979f835a1f60c6e1 Mon Sep 17 00:00:00 2001 From: kconnel7 Date: Fri, 10 Apr 2020 14:02:38 -0400 Subject: [PATCH 16/17] Monthly Calendar - sport_schedule json --- lib/screens/sport_schedule.dart | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 lib/screens/sport_schedule.dart diff --git a/lib/screens/sport_schedule.dart b/lib/screens/sport_schedule.dart new file mode 100644 index 0000000..e13775a --- /dev/null +++ b/lib/screens/sport_schedule.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; + +class sport_schedule { + final int id; //id for each game + final DateTime date; //date: 2020-09-05T00:00:00 + final String location_indicator; //location_indicator: H-Home / A-Away + final String location; //location: Knoxville, Tenn., Charlotte, NC + + // -- sport json -- + final int idSport; //id: Each sport different number + final String sportTitle; //title: Football, Men's Soccer + final String gender; //gender: M - F + + // -- opponent json -- + final String opponentTitle; //title: Tennessee, Norfolk State + //final image - image: (do later) + + // -- result json -- + final String status; //status: W - T - L + final String team_score; //team_score: + final String opponent_score; //opponent_score: + final String postscore; + + sport_schedule( + this.id, { + this.date, + this.location_indicator, + this.location, + + this.idSport, + this.sportTitle, + this.gender, + + this.opponentTitle, + //this.image, + + this.status, + this.team_score, + this.opponent_score, + this.postscore, + }); + + factory sport_schedule.fromJson(Map json) { + return sport_schedule( + json['id'], + date: DateTime.parse(json['date']), + location_indicator: json['location_indicator'], + location: json['location'], + + idSport: json['sport']['id'], + sportTitle: json['sport']['title'], + gender: json['sport']['gender'], + + opponentTitle: json['opponent']['title'], + //image: json['opponent']['image'], + + status: json['result']['status'], + + team_score: json['result']['team_score'], + opponent_score: json['result']['opponent_score'], + postscore: json['result']['postscore'], + ); + } +} From f6927245fda9a7a2fbc1b2a560bbb1e174368fc8 Mon Sep 17 00:00:00 2001 From: Carlos Lopez-Rosario Date: Fri, 10 Apr 2020 14:30:50 -0400 Subject: [PATCH 17/17] 90 -> 89 cause android sized screamed --- pubspec.lock | 2 +- pubspec.yaml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index dd1117d..e01b47c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -155,7 +155,7 @@ packages: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.8.0+1" + version: "1.9.0" petitparser: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 9f02971..cb97cbf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ version: 1.0.0+1 environment: #sdk: ">=2.1.0 <3.0.0" - sdk: ">=2.5.2 <3.0.0" + sdk: ">=2.6.0 <3.0.0" dependencies: flutter: @@ -34,7 +34,6 @@ dev_dependencies: flutter_test: sdk: flutter - # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec