From 3e0ace52302a39e06cb0a2577da23f75324b86cc Mon Sep 17 00:00:00 2001 From: MasterGordon Date: Sat, 12 Oct 2024 14:17:05 +0200 Subject: [PATCH] added collection --- backend/controller/gameController.ts | 7 ++-- bun.lockb | Bin 223605 -> 228807 bytes package.json | 3 ++ shared/game.ts | 37 ++------------------ shared/gameType.ts | 35 +++++++++++++++++++ shared/testBoard.ts | 41 ++++++++++++++++++++++ shared/user-settings.ts | 4 --- src/Shell.tsx | 2 +- src/components/Board.tsx | 49 +++++++++++++++++++++------ src/components/pixi/PixiViewport.tsx | 4 +-- src/hooks.ts | 2 +- src/main.tsx | 2 ++ src/views/collection/Collection.tsx | 29 ++++++++++++++++ 13 files changed, 156 insertions(+), 59 deletions(-) create mode 100644 shared/gameType.ts create mode 100644 shared/testBoard.ts create mode 100644 src/views/collection/Collection.tsx diff --git a/backend/controller/gameController.ts b/backend/controller/gameController.ts index 4de5f8c..e8e6714 100644 --- a/backend/controller/gameController.ts +++ b/backend/controller/gameController.ts @@ -8,15 +8,12 @@ import { parseGameState, upsertGameState, } from "../repositories/gameRepository"; -import { - serverGame, - serverToClientGame, - type ServerGame, -} from "../../shared/game"; +import { serverToClientGame, type ServerGame } from "../../shared/game"; import crypto from "crypto"; import { game } from "../entities/game"; import { UnauthorizedError } from "../errors/UnauthorizedError"; import { emit } from "../events"; +import { serverGame } from "../../shared/gameType"; export const gameController = createController({ getGameState: createEndpoint(z.string(), async (uuid, ctx) => { diff --git a/bun.lockb b/bun.lockb index 8505b9da6deb9a225f9e2e329eea0dc3ea3087a4..0a3d743db6bc8162df1f4c5c17b65866db70dcc3 100755 GIT binary patch delta 46923 zcmeFacU)B08Z|s~WRy{{E1;kv7EnMzq%(+u4SNIZh^Qzkf+(N}Mvc85b=!MPG}f3{ zu*8-dO=4n6vG=GLP1G2p*xt2HVTjS(-0!{jzTY2rey&;1^XzB$I-4`jZ>Q`&e`Yt^ z%ia8PNRzY&zm;FG;HwhL4}87$$(Xud<=M@antNrosWVCX-ao5|fv>uAqN_<#%{l3A z*{-mZG#GNS!DjGT$zZSte*-QK9+Eg>1f#@5XZXNjqmmL*42CYyOF?g~*=L&6@IdJ0 zVXvo!Cnu&SdJRf7G(_ZTu+J`LFxY|Hf{}i9&QQFUfFUg0mG8}A%BCx837ew zNKPA?5kIV7!hRHp2`9v*#HXR|+cdp1m<9Q$jM_5uz*V8whrKkoCYS~Jx~y98zR+2L zZ&6dY=Csgs3mE@$Dxs9l$Uo!zb z$zK*#En}9(>Z#sL1zo;`U&W4iI2eSvSncA^S%q(pCt))Q6o%3 zKqcs*uBv_#jG!DBuoL)M4TGUJxLhrRp*r{)bavGh=uBq|bozY><}6wYW=kX^UFx;m zRQ(W`1ul{8t_>;}I7pU(Su*FkYLiyb_+8kUKxHkW1ZEBI)=>-my~dq9)bxVE4A%=% z8#>c117-z}c&hnjyLhQhQwGdFKZ1nVRO`VUlrzArQ4*Lf@vOeVfJ)_bLXDikKQvHl z-p^b0ivqJnyus}2Q1~%JA24fNuc2DNQDC%8c8(JS4z4obl3*K+^L^A&nvxI~Kf*IH z^@6WD7M`Mi*;1Flj90`@<q{u*)oT~9Ne40EXV?|JvcRC z$VjfB)1a4V14I0 zgE7H#(!m@7y}=yA5n#>%H!#yPgBkC*K^;=fx~S=Tg6W@t;qpa7f; zO%OkuD{}t|U@#2Q z^!|xM`+1`6>-AB?t81L>nKUduZUjn^l!%jpp?Vx<6cadsh%Di@I5pwH2^k|<@;ZIh z1o|h%jTn*8&#(=CEO|m|+K9xYR1DJLX$dJAhM0IYUP5YeN&*UEgBIjiISo527#BY* zg-tOX@mZn#eyTkzCR-gu{Sx}74S>UtRAy^1^ww%JYG7jgK}aVZ0m<5E%+vVTMX6Rd*vA(sNPX6wOhI(B#*n%Z8=AZeI7 z{Vr>xSZ`{*0J{EAD~Mj8dD^nG7Ivn8AGHH#=jeTsg8&vlFS*{A7rLs`up*e#=?K_? zi~`XAuvSx!=E8${B$}CeY?|55k};QU+f`&R__19FmYSAi>8vihYq$ zb=aREBd*XD!OVD17rA2zuk6E_>Oz({TJ2)HvFbEW1hZ%Q4@>dHW;Ag37&ZJR{3^jd z8AFae{W44SYnP)o=oK)F@fiN(6VTanpMtp~?a;y_z!*~5Id_o&yZRL(aLj!N-5$JO z_eSCAoVd;-jx909Y(HfRM|2ByCZrhgWg{{6wMNHmxQ zxjt2`U?g-_*ach>t(a4i0{A&<#0QJ%; zGvoXjY6i36&jO7FGoxfMTQ**^d(2iVIvbo_9sxgPs1A+cKz+g-HR3feYtnkIs^0>$ zfGuS;!!V7}#Hk4*xV(4{iA%;_1wU43511{m0nDcFH!OZcO5)H2H{`>LmCZ!^)8Q!! zKtqZ_?aR*>s1YqfZR)9DW?TnM|9T760?h}r=2O8O1Nv^S@6P(Jt?kk|`X;Pzwm(Fm z{aI4|IG`T`^le|??)6<=-_7-1Ti>nqV}*Wv&`$&UZm%Cd^y7wpyl~HsRBN&wHRj-3 z17=PC^_u*Dt4Q|0ttMJU^m9u$bS1mg^1iwbjQ&8?`+_-`TYxKb{x{G99Kr0{SBQXs zoSR@e9s@grKLN9aR)9Gur+}5|2Ih2Zg$&tp7BKbG8`VJZ0#HKX%jCip4X3A_%>7Mr4l4+Yb|Gng$J3T6u{XK*lPj6ohzc8u+&-)Cj^|6=a> z?f1*xHn#VOEm5|{<6)PE$Jc#$C^NWX^}2(u4|*r0b7;wo&38t8=ABZa*qG)Y{g@r~ zplHa^YL7R~J7S;n)s;@6{YTz=b@{}l_kUjOEv6T#*=Xrk2`%6MrR9q4XUbnGWlWNH z*9bE%k)PuIz8vTpCe<$@XS!NUlZzM(LGp`;VB;bAscV?Ik&VF+g3=X{jgkJw;c`aJ zFyktDH{Q?7PiuxrrA=~BEsLp>$zTYULtTT7Lf%~~%zO%ZTSPN5nyGqGgCRl=tsN|t zE+z-nwwO9%FX|(|Xc%GxAw&uJ*{pNh^H6&lf zPr~F;vNSb=gwoazv4PMUEvN{s6t9|?YF!m66B2C59zq{A5c5+_Vj!f}O7lTzC1*7V zv4y~)W#aIW8avCmjV#h8XE`5q#aRyWvq(Wz zOttHBV7#aqZ0xe39#N`Bo=Oj+R#}jmtF?0Xm%jCsgBoK|@RBn@DPD4JV~c5vmoi@v z?Exgr07#MbS!rgw1X3SGaz>BzWvDqD5<5$hjqd*DpP)6UG1B2^BOeU$mwNlk z`4JXrg|8eGX_4}L<;+Nn*|m{6K;YuxFC{dR^AWb8ksQ>_VlL;WCWd^_#xZ_!ZZnH% z1ad}CHVZZ#fQ0siR4R}?PAMLeMc!u#Hm!oxnKtupkm6Aaqa5DM-xPyhi&5-bAq^<7 z+hhGw(ly6J>Rw>q53Rl8Un&HjXAA5@psDtKf3Q1+YUxM=L*?977V}{kdg{^4)iFNe zbj>slnp%Z#Aa!Im5*Ee$D2usom^zj)$58o|VRB|`i}X{NoZH%BZi+^YKq3a&i1mIh zG>$q0TiJ918dj2e!RC_T1#_=ofGrgEv`IEjQxpzfNe*}QH4aq5h`Np&=uT;j$5OPgM{S@$sI4SRcy&- zqb(ki8oC9NmIx#@;m}rkX5%2Kwquag7!{-R7~LUZB}97fK~nwhLBi^QqF`TCP2(Ub zWtYBfEoXMMn0{%Cks^n73$ba3K9;k(2Akf8)LW5?wr3!1agbsaDHoFJXWs$iK(VDm zN>rq)kkq)1JL-PRAPrDLZ93sHQIQfMbyB3gkfIf-d}lq6BuGjs<}V?kwmG(PIF{o6 zU2p?dpk;Mc7Z)W=vWu28yIag3V`WHzi?XPhYsab)RBbdglm&BnoU6b2HZ;uK9J6f1 znjhH>Ljf8_pvB)jPSc8V+L}MtG?P5;-2h{EIkP9Wk?wMCPm6gSW|JI5OT5)z}T+guRlzBXnv2e5hp#yB~spT*?Umw9BN%*l|nbX@(Vb$#Xheirjx&8Vy; z<{DTG>4Jtv(fdMUa;OM4gyqoKuf9Q)4YC*ngn0p2d`wZ{HuDT!_r?P*T0n zQXfOZ0>U`ZiVaX#A?0{(ZV8R8h`z&7WE?a#FYaz%L1Sklbqkicfjo1vGA$r6SEZ!V zy94FiK^F6M7}=p1-{@ZZL^WAug*3N=hM9{2$FLR9dO$-MI_DX*Fld-1js2xIgXEwj zi#cbI-o)5)q#c9g+$4+1elX8{*qhA#A+bV;(;9;Z8dE^;v_g|W!&=R`gerI>sa3#G zM_$R$th4StXl#BoMAHDPtIaK7yuBBu2jr%^%TAvH2y}VRCM=#XN49y0)MZaIpJwm>e|RB2`G1GlygAO4h4@ z?ZvzX8cU{>MS74d2c=ld{=@Zpv1>*{3zlEh36^#Ym-ACB(u?78P%6Aq^Z~|ljDp5$ zVAsQGVoQp$WZi&K9k5(_98=Z3R$cM3p<#j4*1uEGB6ZDVKSJpY_h558By|Fe>x0gP z#;Ti@&NvHA9eHe)YH512V9rbNX>#UBi+Kf%zKBpn9ydL}77EkCh(j;b8L3thOCMs7 zfX0-Iu^CO9q4~;L*ru;R;%LM=fDW%ds_-hE1`QjER)ZtZtTiyFBRyr^YYIuNfw8r} zl$|bTW?0PsfRU|LS`HuXZ+;1_o00|XF$`x%tG$w{&*v?;iJXX#fZ87;~^Mv&RO}H8oXM~cF`6V=UbTewd9ChDNR$Ox) zG&X{A7L#1ZDIZFEj^hrCgiP;2QqP#bKq_!FyT7Bhk&=jM05ojP7%to2k#omd%uirY zE5aPxj@LCd`&wwNl^hv%ADUXyaU=cBttaRu<-#%-8n;Vj12SEJhLfa6u(|R?^~j9b zI?`WCnJDMySj%Q65I6eKX{I7`g!YPFza6L1On}ZA0g*nHi6^Girv4%CKvRalc6&Xe<}Tg>my)5j-A` z^Jn2>*g`pIw#9UQA%{6XnmR6$b7APP2uqH#daY7g$X3D_QLq3xZ7_L29E&uL`8rt909< z0_i5CD8LuE*6j66uVg+XZZ50$9`Nrr^$gJr?e^$+Fz6}TVVsNN4^>rU`D zb%lmoK39Cq+$iU+v`9BL%K0lTCihKPG36Kif~DS@nx_Io&1RQVqLIlEu`LxRAd+KCKRbZq(nvf22z|NHQ3FMkc=@6 zlIr&}BsFfETz*Jo=mtp9l*|?P6l|2ZHR!ZQ&R-vt?O{;P+;~^n2HXHJ0^Sp8c)A#|HFEafe0?g<-q4v~KQMz5v~V*06E*uFFb6fCa3qfemjX`!^F?NQ ze6li|HJ<{33D495=74FJ!F-V^&choc3NQ=098ABJU^95V7QPY8mf8uf1U?S71D^xa z{{ooP`-TzqF9+c<4EA6wESZ8Sq+W|#ES?EgVl^8b%y#IZF}tH9e?&HryWvYq}; zf`9hoV9Y>4I4dTAIW4DxYl1f`bC7~oQZmJ@cyk4x*6d{V@wb{zWHh-EDQHBZ)TJWIDz6Ao|HzDMqdA&b3cSd)7t`#vn*B}849r?MnaglFO(!$Fd=YJg zmxqA~SJWKHbf~21g_$Nt&Hk@2)2pn-BQrlIev^eSC(Te*(+e|AE_ma{;I8@A)BMOx z*hACF)IBx!0&@dv2xf+jG`pY1+5Vak0OqSOGoe7(88H~lz6%30!3fR&ubA;8;m0jJ z2F!H2fxW0b-XE~p3Qu`AF9 z{m-Viz`$cuB$x&00LDK<7re1x(Nx~TOgIMNM$@x(fy{H!IW6En!K^V~9vVQ|io!hqi`N~6ZadKb{gF9KHURkV zTz9AogL2!!@%LZ9?m(V=EdiAAPk}EoTjD=`-BIYaLtT^iAXARY|I&3wq1z7BpM&oT zz}@9Kz!taxa9aLnt~(0dcJNHhjQ^|G9mr3=?a2OraoxeL)^0np|6g2p6uRv||J$KB z?DJAA)<0o()tjz47>{;_SJ2WSzxldD%}=@Q;QafqUw5EjtZ+jxZ>tQxT8RrYP5;*G z4%u^?y|UUAzS}@1%ALpm?l{;IZ@(O2=-&(H2>jn2$N%m)lmUZFj{@d|{@)!3?>g8h z|GVS(-yO&Q?l|6b*TDn9|L!>cop&M1spsF4AlLB!-Eq9>ZiFrK|D!vOm!)5F9;vVG z^}q5mH6HA}ao3VBtG4^DPKopzwm%L!Go&s7}eQ?1}?s*}~=q<0mfcjlT{Vqn~yGyYbQNK&5AGAiY`4Z{}ZOEl4 zqrbcx+Q7@G-{mM{pqzLa^}B-lK?{~0ub_U=vaUoKL*--8(yyX^SEGz!a>iBE?;7d{ zEnIfLhWbI9aV^T&R6YxB@^#ejdXzCzo^l=ayMg*aYc2=gK>eUCyAfqP%jVtT50+<7-t@)L_qW&_9DA|-fsJzcA-_(P@7;9B?(y}^J25#+ z2Gy+Ed3}eAmc=&=AM8DIyLtOho^9y-a>xCc&zm$k_Htx?vr>09oF6rK#FNn;sSO+|8APw@hw%se(g;rQS7~ytDjQ@A_x=4BVGHY5MuZ zLm#`1J=L_u{)jq`j#2Tcdmrz*)nUl;%9~wU+|T`S_7@F58}W6ApXFt@9I}%)B*dOc zd1}8fQrb7=hiUUR7}I=0lbuIgKE9?~lf#qkSMK_zM{JE!oBIcvE(b)nds^Yfm#Ozn z;+-#lDCu#2d&RniO4p%q=`KIESzR_~YOUtWo35?j!)JP*mJ3EjZ{7ZntHTFe$nEiK z&bph;PCoaVLFu^Bt$Z znse*rql%Z0-}ueB{(+8>C!?aaPAWd=%KoRNKe=C{W3_{xwTi!3a=7n``5zwm)#lOq z!CU9sTyd`b9-rXQ+pbgL(*3f3u>J3&2c3;=yLn(hP=3A4@dIvd?bi6xNt=M84>p9D z&c!BYj2ySo@sg$0d){sp!j3Kb`3{ab2jbmFy3cc>LqiEWZ7{e+&e$1oY##0#vXU?XJoA#u&Gjft6A@+jjtbi zvh(sKg-X|@aOu7+5vzXa!5hFp94<0@Bke($iyZRJgQ4y~{4`25R0*2{{G9w&7s9hU!Ae?OzVY1 zhZZVbwA}J0rt2L{`kPV4SotY5ho3O%Z$;r-N9%84x z!*soeNuL*muhZ;?b_SaBohW0xoOlP*^=C|aXbH08PnfR1VAB5-WgH+MgLWI5=iMk{ zqMUIT)Ac?kJ+#5H`#nt82blEtqKrf2v(TPE3;j9DI82`MGnS)=nDo$w%YnaOIrdD0{T@UaGvuex93G>752K8u<@FCy zKWKKpMj5l@*k4h<-%&qk*|PZ&>h}codlY3HC+~)K2AcD4QO5Cd;%}(mQ`8UIMA`8% z>X(oDJ&rO?l8-^V4bAiSDB~14<9F2W8R`dZn(Y1r^?Q!`J&7{Tkk3MU0xk4ulyR0k z?=FE7IT0{H>nh1~LaG@eRch4)4BQ@k&h zJG_X-SM}H9eW`4G8Esr9$KrjtybbRwWb>MA;Ic!y=J%L>wf2CLBwG{vn2w zJ{QMGM}>1*L#8uX2rLOLO?l1_@iGN4mp4(YVW zBYi8v+0NgIMWpY=1JVzoWjW9pv5It7JSCkI9m<2wi}j=n!dL-xQN)riiEX6I!dww_ zMZ}S=iru7ZqHHD5b&*KAAr6v$6pr?wn_@WWmN-VbEnFNxc_M>!N1P=6B-|a*+%25Z z+%p`}-1o#;8lKP)S{a64#FWY~d{7mJdo(-{fmL9LsRqNcDlq&i@@TNF4nrF!7=9Cr zoM6~R!wVXI7cHG(80Z4SCTAF)il;O<)PSL9RT!R$^;KawN`qZB7+#3jYA~d`!my8q zSHfH!2Dh3p45@C6l8i=?Tiw`IoT0_p1(qU4F~|j$$+ciPPK(JXD%XG|pf)U7HDD=b z6kpJCn-))3Sj*!scH#s`K*Vv!FFyJ&bp zgTH9m5Qc&NFl=fFL!fv{gF^reJ$+#a7VCXsI7)+EBN#$OY$F)b17X-lLzpo8!Qd7I z!w^3h!o_YH&d}iO4?|Ot=nuo>U>J_m5Gfo3UY7>0zy5GQuiaE1owCNRW{#3nFIZU)0~8WMzKQy2o8!;sY! zh5_Oj4Yz6VjDR6gWJJKQumubkX&5ZrBVlOK5{4O(FbolAX?Q|IXfqgwi7Cxs_@EUG z_h=X{0-M7S!@0GrISi>Hj|SV;Ftlj_Lz-CB0)|~Qyr5x}XxS2mfo)*e)Dnga@stLK zwlMT;1;c2uz7-5dX|O{#8M8zz+cCWz4Et!v7UtG4xV492NNX6ziQP1up~1Ng4C6&& z8yF^cfZ;d|6NO`27y>%NkkuB3N#Ym{w`uTf2g4MR(GG@%onW{~!!+UE9)=d3VVKb# zh8f~44NqtY?Eu3pF{J|xA9R7?9u0FuU`H5Yy27xmBMh?0qro;BhBlpGm@gJ}f?*d8 zFK7^=WoH-$#=x+tGYpHwQyLs%Vd&Wfh9zQs7Z{GxVAmCfWg@mK4C&oq*hj+(VUC8u ztvd`uqG4DicGGZ%2Im+U)`-Ly7$*0C;W!QN3CCC%0(!!b6$``r;usCLY4Gd@!+Md? z4TgoiV7N%bhr+!(3@v)YFrzyRo5Wcfp3o551BNYPN)H%5=mWz&8n%hRo-oA3!LY0+ z4BJH>4Yqw@XwwUZPsE~LFzlk?1r0kz%ib^yjE7-UZy0uqr!es3&5{Bpu-}Ogp&j5GvU||gp&j5b8(D>lS2aNn8+aE?YylFcfrMB$9A)ApIyDhk5&K@0s2iW0*PJe?8Oo2wBJR`G}xbrRivllDJfrc7zuhN){~wK<0#Mz5leb0wvk>5 zbGk8FGDxCty0NQdlteCAoEd|Joilhiki?)2gxE;p5ZNS&%9-Gzl1L#Jlf)NfTS?Ry z4K_<6lU!U9r@%ZEj6psn#W<3kI7=!eyt6>1#S~H*ag|h71dauj6LU!AMINbw2+syp z6pKie!~>GOXqf|Y5UWUz;wh=J=r9gcMXV<|3FA8;XAw)PDz=fT3G;YRbrDB$5xYq> zMA-=-SCL4nDGriq3CD?`+G04VjyOhg6E5$9+;?WYYiw>O+Rw+RIUpNtOfF&g^Skh# zZ@eXMtzlDqWa5YfeuACRMC_ku>{h8rg!1fOj{d0@pCt{E5j(x+8!s89&sy&+C5#J< zCPOq6IXDlSF%y*x(K~-$X!I#!8ru&~;xhH|Ox-R35BlH{tDGj_Qac|kH2!W>OVM$N zW_V@Xxof5IfT@yFF1YemQU9M5Kbo;~<~n1pWQs(oN-+L)BhwX)*Bfmm6wC6VakGu| z>&H8P-eSbDQvV;+jCi=E0*lvN$xWVKv*ymN>x_4e|9k(xZGk(+;w@^jkMKNeEs?WT z!k~AQ>SY^VzEWQd!Pi@qryWXD!AsW}&q=Z1k$BCAe;Hh*CTO?`8$}yngJ!#}`SH;p z{W~3bnvKtThQW{DrZL=sknK~w#C5u*~QK4ZrJx1BEuOpyGRHa^7KgeAwT7;F;%-oU3I--W`LS##uLu)DNOifcBu$`Q?0 zLbH{DjSr`?03~7LLo8*1np!3`G(Uc?qZVu|fU9QXnFR|EF zsx92ANNf53yBq2P^?<#|Z6B~7;3JfLta1my=R*1X>|h`X7y|GM8`FU4zzkp}FbkLs z%mL;CGB6)l00>|qun1TTECH5E$a)!s<-iJHCBTkf4Xgpy0`CFqfcNnMQL^{s!{yC@ z=0FReCD00p0$KxYfObH8po19hBH3s2d5%#)I>6!57zhVAA~*ud1LskFehcq+G}IH| zDew&7-w$2^93C7w94Q%EK6u9O-0=&0t$-+?Ex=1+Ud8glvop{Yhyh}OZa^=fH_!)&1Ns8-KnM^D zSOBce>peYc+=MDLsrytM|;Dex^fEU0AP)`6Sfm6U~;9KB3;CtW);0$mU;9r2g z0{GPIA>c4@1o#a22k<#?6gUQa0q`;0-M~6N0P((f;VjvEZ-%}F*a~a|J_2R{Gl5ya zY+w#B7m$H@!m%pWmK6|J0;_=4z#4$FbQtgw?f(kk69)XANykr8S z0X{~a0Q3h200V`ylhiP@6~ri@H4qGh02KgxzyWXsDg#vjC%_q~3RDBCi&ZtGI@x?G zcQB9y3$e40-b>_02jDD02eiW<#H5|1@J-3_YmJ3;2#RV2KZEV z3XlvKQ6qkL=oxSWxCC65(B4lV{0{JII~4$apNC(O$^*tDu}J{Gwvh|)3n$%y9zZXk zH_!)20Qv(1fn;DfkOHIvBY-qu6p#*N0Aqn{Acx->8VBJWU_3AZmumwO0kP3_dxH9)aOT+>Ef-Apknu_=%fI!6g5vYhX?to{3^H_>I zz$Rc0AOjI_=68MS1KxlS;ExESkT}1zIv2PJo!_3B4=ezhBTh@870?clU@HPN1OnjO z0k)1nC!jM>6n0M5>_&Ji2JlNn{QgiFocSeU?t&!&eoe0*z^4k^0_}kIKnI{B&gz13iGAKrf&-&S^j4PhgJQ9wG70b~NBfia>3){xqhAWjCR08@bmi0%Q5L<1i6Lb`bQHsM}bBikJ+ z$2iw^uKC;piU7aCwioyXzWk~&ALJYe3;_BAcVXw_)Qf>dKzo2|`fOkpFcnA!c;M~} z!~uN(uIoL49st()Qp$qQg&(JELm3fXQ|g_~w74Je&rRGLxJPsZm_GLo?i>6IXc?e2 zP#$OsGy(X(4{&d21n>aC{f7HaOP~eN0B8<010sP4ARK56a6iG`lC5kq!BB#L0KgyM zp5hB|U*TzmnKA=1_ZaRqOxy?HBEa)UeV_uMhtuW;V3p&4%gq1wn?F~foPg}X)qtwV zpZ|q2|L1Duiv(4`&HxXSl>zECfU25I-|9e3ps>vqx(h&G`Ve|NhOxjr9PyCE4U&at z0V^Q?f|{|0Y|6s5r5vc)m;iM>T=&)a_4w=>-B*vNr$t|OV|EkGsc<5?6C=?{kE|y~ zUp?OInX>QoFx{WyNRQJVGRGFfU>j6WLVdt7fCmrVi35sbqi{qPiUX>!jT!54SSSw0 zB7pYs;Z=8WwYD_6QE$y$65LOd`-0;&c^G&I!2M}3kO&MEC+kY~#sOkm9jW{RH_6sG zND+-mBHT@~7a!M=%FrBGIPzpfpU~|pU!?6?ldg0U@E9wPfj(R&OgP?pPy*e!G z>xCE%+uQp+djW#y1M>hGV1u>>*r=QiK0s4|^NRDRKENS92jH;x0Jx%XN^pJU^a%zy zZRP?T3kv}O>;{$sOMvabN36&;2wQ+dEk@Xeu({yI0S(2 z0k)76fUdwxEvy;jcz`FX;vCoRka>;^ELCt9Xy5Af4jaliz;LVTPC zvJJmOcm&jd(F_y=+5_!?B0w9UHBb>?fr7zhfGD69&=QCMS^(7m7WN_h9su_NHehqu zeuYds!|Bg-f{Yl(fe`2%0QLs-(z8IU0TXowDg*qCsn>)BVnJ9V7M!(Y;aNKyfSI!b ztSJl5iv9+$vMkhN@C)Q`cn&-R@`0zo6HV520}_z{BTy7z1|@+KfE`c@C=HYaDgfmG z9xNRIC!h+z!c(pa&`!7j*>&(%3vdN$0<{7D4>ayTU4Vm>HEjUY2l&6zcmckE56}?s z2O0r>04u^4WXrL&ngVQ@Fn~W4$JPh|^J`n-?El6PngEdiBhi70us_=ZdWrR#u)pcY zS<9B_2E+gyuw4KSM)o)5Xdo6~>#>mR-Z-ES&>iT({^u;~38fd%8(^Y(Ld=K>_X9Y( zY3Cs7tLdBx#D~!L0J*?!U>C3vU^7=n_y=HC?0xV$;5~rr-l}W}D}fcjV1S9e15N^# z1IvKnKsDHxf|me`ff~@O0^=Yr0tB!CaD;6>cpl&i*##(kq?2LirF(TB`5^mt1D7gh?(9DIcn)idJY;aFi9<=1`KD$I-p zWQ923IDS}j7Je;w4X_$OVU!;SEol0}iRsO&cMGT3dVm9x)2FcS2IzXt=&yGV3&QbK z*q0UIjHv>4ME=TDae<;w6P9=rz!A^Hm2+@B{i1k%pKB!3vgbW(++lMp9O#4EKXn9DKYK2hM3sp`2~Mo*%#E=Ix;f@m517iF=4zWf>fptLK&tE*(N9hrywdSEE2L zZ|{$UOQ7V4V`4Drn&=WJHFRR9uqd-?uNpIDd52uMH}Goc>*b9u5o-e_A1Agfj^Q~+ z40)X%&KOWn@$hZr1Nu)Oq%;GnX7^ADM>`?*Olc zNIg)51)-w6N;M%TE&4Z+VTbK2+Vzd|J$v-RZkUtHFIsLC42 zSsNAwgR!6p`mZ?aKYnG6a|0P+Ma|KF{>mDn{{po3!&%{%tU>w@fx8ZQ;oBzY))s4s z{`1kJ9{k{6I;hJIYe?H-VoZqS;KX05W|!`t(D-?cn6DhI9({|6t?=;Ee;d2ZnWRPg z2Hfmu_0WF}+q>lT?t{W>Wm!We6caBQSN}=!iWNH9osMz}vU=!0aNXpk$BDH&u3xi; zY$zsLhoWRVQ8JFk%w@%U*N@s4Z}s@Bn8<;L^ldS5KMbBX;8_-)=W~6}x&?jS#p?N6 zG4VA#{q&#Tt}=XHjhM?*ezbb%KhWJSWnxU<;Ro+oL)>hIlLe{kzwy1lhp$_Hj}s5A z9#OUeKZ)Ytr~f**IGp@s+PJQTT3P@7@XxwkbgcfJ-6(6^@wQ?)Y@K={Hr#*+>e$j)7Bb-k+CuoslVQLWeSF`<{{NAF7_f9seWyUhK~@!g`-c8 z@47#p@JR>jQvY>Xv9!=|ko2y7dk6m0q4pPp5lc;SGgSBQ4_kfsCKVGKTNH}<_PXjZ z{&^m+l}36^|F_g5y_jg+yimFSY3u22BfVbZx5tbrCd#mFunDwoWzFkfsLyM86_i0w z`L#CH!~aGLy;i2b5kt%CPur1oNqc>>v4*^sn_kYpNbB|8-I|s@8niV1UO&EAJzqaN zSVQ!7)6>%Q_HXaYx2N^?lIkt?`UYk#$J=<{dzfl{J#l6Qqb0Nf&+CS&)r6%D;x>Q>5AKnXEvApDU^7tl zz-I+R1VZ>>DyMgkS;f|zsKpTMvv|c;6VnmbX{hG0`pM7+Hb*NDvF1CznmEAJm%sxT zX*n%R8|JpJy=}ObI?~vV5PZ(hnfmGOGUqQ`pU4nwfp~pYO_XXYwbnjfh+%E-oalvha|^fw_{$oiYH#qh8e(}2 z_*o6nryc6zg8Ld=a^%#X8u_(;exjc)b3xt&C9*Iq51K zq9q@(wY^kM>f$P9x5p_!{n`uD}Db~HfmK0QutF!Z>w@r9kDeY zRi05t{M->$USCJK1j?CkvrP5*#mY+7Dj%t{fNl1D9TCzAj(6c$2{r#=eYNZRd_T-r z9dY_HNNyq-9tEwbR-&L)rOF8JgYa5zVrn0$mql-cx3}TDZt7?JBTE{5_T(MgS~$)4 z;6t+?Zi3y!%+8oGAHjoT+J9fMoqL?xeXg8$@aY%VH*VrWXQ?hf$tHJ^9Ev;Gs5c2E z+(q3kXmUq)#m?{xU8U+`b650}=Byi?Dq!w%GFM%6;Y#|Rig`-%%13MGx}ri?Yw|Vq z`C`K~$ZzppiT ziPfW%ho~O=w}!Op`Nx@4Fk`f8i;!+ov%fJ5k9dl8-3qQJT$JmHGMKphV7k7Y^U0-i zPwi1U)sJJw#Y>dxj(Y1{cn%koKyM_y1JuUx5jhO^+>0TtyUzt{8EaKB}TCrd`{M$MoXL0bkzeviM^##&9Bys;th zmgLsdDm{$7Yge@Pz20P6Nt~kK$@M<7OaEeXdY7GU_59B-OHTceIT!Z>HpYKkN$Y>c znz_DUX~X^X1?z7Nw|}WAIK}>=DYSK0?-adIg*)e87;c5S;15&#@9#9P4_JLz{i|K} z@7qECMu+74h?$cyqiq_B_6cb2GB{T7B4b9<>|boxt_zWjzSvN>dpR`}6A~n!Dz9J8 zmBCpAivyMi<%-jhA2seWsn_pQtd2PHR`1VS6CAbqVZ7T$(>Fie9dX6#F##bg#`~XM zcPjQpgvlDxx40O}xPLyJ>cyysD)0zc>1B<`Pq&<&iQ|sHm$$E1fMI7bu@`Zj>LXJg z0r!}$Ud?a~_OqtWyE&%*=fk+3x*KkrmH~)69v(ajPH34n zV&hL~8?7FH{s5t;I;x?Vj<`;5+#P+n^j`242L|ATbia{!L@wed+y;WD`H3Fn1%6`o zK;*s&n?G|u^u*)ImZSGp+Zb_6-_WZOHhhHO9GTN}$Fqwk_pV5_!J(~zmoK{Zs-L*T zxG&+sng99fmnXX4{Bf=7fvASc{_2HFi=k^HUJkaoXpI}-zhE#5-W3jv`rStZXYXH< zXR$h@_=`S?NPHeVs>8#@ru53oowr@HdVGu!F1SBWo_xW!`S5qFMLy~;HZ$%ecvON% z{r^8^-Ep0&Je~Gq!_wbdJ%R#6gF#3= z3Lb2-QN~sse!Wn}8qzsXj2(pY)!S>O)%!16Mr}I3x3}%v z`$O-sxA*C(F!iHS-{Cbw8X~*#AxMTSV0E1~>xTuDlm3eTI$h& z?|dq-gg*Sk%)=&P?GVYwZ)j7s4yjXGy!`mRnq!nYD1W(0M+iSE*86Tv%E`eW^-w~v zk>jtc5u)T!lyFgm+PO!IwHM894>`onMdBFln<7MGc=#RGJRI`#y*qy4mtghy0U;bR z%d0fVJ)IZd%^GqyLd;~`SMcDFwX=`NTfTYZ=T?u3k!rq&3_mxoohLQ6hPX$H3oKc% z=5c;}|7P9`&K{ua)gv7t_6Rw-s*Ljyx4d@NkXezU z7vrwc;wJT3{p$NUyTh#>yS04#R(ftOU9G}nYsm3Pu@P~dF2jR8GudY2z}{tp(ybm3 zBgGY_UbLC=yj{-0ALo2f-oE+oRu2b+a55czoKtPg+Agv+#G{$;N=Do;Ev{eduXe1O z`*Eh#W1cpeEWM?(t~jTnQtPHt_~1?ZDkcOMq7{6#GrY+UF~>;(~R z#8#%>8y-AVg%#`2KV|ZDl1+#PZgV{5GQXaFncSTXo^{ud^w@=h=y7Ru4;CkpmCE9`NAe zS^C;ZZ;$6+KDT<%vi+@T#1X5zi@2MDE#9+>Xisj|MGT^SPZzNqy5Es5>MZ-ZVvF##j|SaVW{UC=@dQG+PgX3m zZBOQ`p$nA|WjE5&bh-==w&~T$=SOU7`-Lq$@E2h&B2T)A>Z!=BVpmc1U9fLgaUZ%! zN|nkvb?&NeqMlmx{%6BJ>f#yjV;N&YSFt!%sxBSrDjH1qb9CuKSMl?^SUfs+6@DY6 z`%;r=QF1hrZJdVd|EOru7>ZMuXmwTSa`tMya@C?TQ7TMr?xMY;#q2cHc@R9fvMqmi zPty-xlv)Q5o?);$rD-AcOWXFXHfQ@CC9blve{~1U}3Rj}VQk3p5@!u>8*57EHv= zYMKZeo8X z+I$vjUkh#CwQ`G-)gEj=X083(M}szKo!;Kp`bZA$rjBIi8dqHpm}}rKkIFbj+jfZ- zBSxbf`?`q_$YI^Z1#-LYqRbeSE4I5DGhl(|JeR}eSS}p)I9lQn!aJJ-rEaZnzP;ZA zrNnq*0uRxuarHEu{+z~GEsfSa#YW^Jt?ntl;xygbQ(U3`sF%negHlxQBfPSp*Xtu% zWJ#@^s>iAGt^WI#12-r3#oydf8fENmixXSnA=T+CUNS~Zyl@zc6i&yBKI5UQo#G(I zj+M&Q?AK5I1f36N72*!LeAaxS<8MfgA5%~{ME`oMnhdzL?$ zRa%`m+8oJX=CMfM3>4LKP?VrSVkr69Ah9h%zb&AH6L+4^9&V;2T=!$ z`#I9b(vL}E-8i&`HeRF$N#YT7zfwch%6#Y&vpRp`tC~toC9f(7;o5ZfN#BdT%iH=Y zl~F?04;4M$LBk{s6C>ZTrYR1+gTbv$9>4p;)r3!#xY>8K?0FE;(M^G<#XoIv5iuSK z73wvvDq`+G5?M<+YIeG7VRA8@k4bmIZ!*5-^k z(btCmuB3&&#}^;f9YZXbfIn%s?y2rvv7i2IT6*ao|7^_OKtE|C*6GZC2Use8M8xLGRA$?L05 zYi)zocgULh9-EMwlsI$*9yIQpGkQyz51y1U#$+g8FU$EULxfC1xt~IJK+S|}n8&%H zp?H{v$80VLWiv%GJS4YFF?ABk-#An3r;b^62D(#xraE3apU-rw=M;d)9y-BN25IR- zHaSx?#{GidSlGEWZJ)DEvYY)ip0QS%I{;67X=&86PnLUh%J^B!9TP{ro2V--%M`hj zaVFT1DK7A?;&7&TJXxx1Ift0I-p+{`t)3=Y90{$|Hl=N}l7e#dOGF5_`DsVTmiXcL zrDtl0KdQEUwCFVj<@ypHRp4AAc;G`0z6F609lYtPDt*S({G#T8K~{2%xPsK3T*jy$6V8o4=uqkF2VC~JHKJ~Re0o9h z8zYirR4sDMf)$|XF=7lK?dU&7gscMVPeWuOJ(j7o&GKu#eVlT%^e|}UF`_MEisw@? z3-xCyl;=Ghq(TpS*qh+HY>dd6hPrP+YCPTzS-jU}PTc-ONR7|M;X~YRgs|O8oP9Ju zW=DzPNl`*3FV*Jq$4fc49m^}+3yk5a;I_htirEWrJ z?S)sloc=eg<<%crvCk6A;ptZco_5I5uXScUuNA*|!4n5bj=}l}VVzyGo4Nmbw>sBn z*m_%o;Q+lGQrW>5bi^ z4EV{};=oLF4~A%&1xP+3N9{;M;G>bNn@<~UEr6DmUpshIL=h{_Om}&C_Bfu;(<`w9 zAzbk8#BDZ(j#&4d7J`a@nj?D5Lh2{r!3j{L%c!Y07dUZAJwZaZs#S7}9>u;+Q%7t1hO{R@|Z4^p+qo{3O zsjBZ^&+RuQ@s^Zf{=*|#dXBn1X0%wzX{}Fh?LjI(=ThoN;qROdTgrMpcc;zR(^w0^ilNPvg2%vKPy6*e6Gw~LOQlLS4Genj@W@$+(rBd+)#qWYfRQ6b zZ{33A^(VUY#bdALtkhS}TYoUD(j;{S-df_^ko1W=PNUS^ZZTwEdk{<-K1pm9$WC9P z)KXV8VWR7aYB@@UDy)=HuVA4@R_tm?mB-rjnr&FX$J#Kwcowp&^rYMU=~wi{7o!t7 zU0Hy|t5D`zOns#-Xco0l6;0>>wLvQs+KuD+lQg{45d^447FF*3>ul1@v^(KGElww$-#D}IKZbY%gq$$mK2N)9Ccos!fz{m zp-J|KDWch(e!?LOb33P^!!nOb(s2uN=BIZ*eE)5>@K}b`^etN;#?tIe(FY#?Y*5ag zEv{gv5EqxJ1LzOsP#UW|sr6j-P|e@0svo=xZN3}kie#L{{N6ILG356kIi3`}7P`3K z39rF347Wq9f~V$+{i`sj?6Sl|u+!T&-CJ`-OnPdoz)T9SSNxyT?T~14v zf0%o|@B5u|&pCVc+~0TZItA91lO2W3IX0(g4|rF2!`u$Y2I$MhWKtY_Z+!FZlRw4UOI%jpSJSh+~xPn0L!K zQdvkDeEEG6^=1_61Ff(b?i+9A_k@mn37u`URJ$C79^&YHz6OcG=UNaXD;kCBn5cEn zR+H~A@OKXDpf*o#gk;^px@~3$X4u-`^(L_ixEcMx;PomX+W`zdCxRg0?^rf~_IZeo z$Dy_%C*%HF_emO^ckI}x;B&kRT3+XgL?4Vo$8dB$kBBgM$BvB-{?7MU%je<{E$`T| zT89|q-3Tq?^Rks(y1o0kN)!T zZ!sGlXoi^ooQ*}}xR&u|GRf;kDl}CYlQKq-69fz7RzH)~HYy-uSXRV7L3S<3rI~Ta z{Xb)i3He)Xw6Y7K7_WD;Eu=-6o(mRU9)BZ7a2rbSM&>d6#|z;7q`UUk6;^{3>4Kp6 z(Jp>*ICIT|y1g8d3q^)sI^Aq4vyQd+D~mmf3g2b$zI-cj$x6G+`o>hT=B6tZsQ|(5 z+;dxB@Y(rtPYFei1L6V5w#+_pV8lC16zK&7yK=#c{QA4G^9L0l@(d zJ7MpAc^9z7kHug}agT`PKBqd&5-pO$WNw0#3Ni4 z`(-LcrbH8t-y-zo%9K+1eyLKbM4EHVV@vM+LQ$qP zO_Hk7E87_h(_HS#SLAC9i`e(IeAH=&j3P?2)JjRJ+Ndl|DN&@$QdLHU2c)WWqXLCQ zsg|W?N=2z}$<-2>T&l!y;!0Z;N-0pJMjDku3BLr)QzTN$Ac>o1gs7!iC}N5c>eYH? z!4`#GV$3&^t^q_1H^_Ag=6&!L9KGbONhK6#uaV6a#`~F7-AFkr9Xo!B@p9p4+z3z> zDL|z|jJJV9D&v|@nJ8q42{LfFo}efxV4Gyl)rCqfGxjSNUtDHF961DcJeA@rgd1sq d4TD7~=;$!xZ>XCaUy70f++iO2w5yC|)xR9x-Sz+g delta 43480 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 -export type ServerGame = z.infer; +import type { ServerGame, ClientGame } from "./gameType"; +export type { ServerGame, ClientGame } from "./gameType"; export const isServerGame = (game: ServerGame | ClientGame) => "mines" in game; export const isClientGame = ( diff --git a/shared/gameType.ts b/shared/gameType.ts new file mode 100644 index 0000000..e92e27c --- /dev/null +++ b/shared/gameType.ts @@ -0,0 +1,35 @@ +import { z } from "zod"; + +export const clientGame = z.object({ + user: z.string(), + uuid: z.string(), + width: z.number(), + height: z.number(), + isRevealed: z.array(z.array(z.boolean())), + isFlagged: z.array(z.array(z.boolean())), + isQuestionMark: z.array(z.array(z.boolean())), + values: z.array(z.array(z.number())), + minesCount: z.number(), + lastClick: z.tuple([z.number(), z.number()]), + started: z.number(), + stage: z.number(), +}); + +export const serverGame = z.object({ + user: z.string(), + uuid: z.string(), + width: z.number(), + height: z.number(), + isRevealed: z.array(z.array(z.boolean())), + isFlagged: z.array(z.array(z.boolean())), + isQuestionMark: z.array(z.array(z.boolean())), + mines: z.array(z.array(z.boolean())), + minesCount: z.number(), + lastClick: z.tuple([z.number(), z.number()]), + started: z.number(), + finished: z.number().default(0), + stage: z.number(), +}); + +export type ClientGame = z.infer; +export type ServerGame = z.infer; diff --git a/shared/testBoard.ts b/shared/testBoard.ts new file mode 100644 index 0000000..fdb2894 --- /dev/null +++ b/shared/testBoard.ts @@ -0,0 +1,41 @@ +import { ServerGame } from "./gameType"; + +const rotate = (arr: boolean[][]) => { + return arr[0].map((_, colIndex) => arr.map((row) => row[colIndex])); +}; + +export const testBoard: ServerGame = { + user: "TestUser", + uuid: "C270D7CD-AF97-42CE-A6C9-CB765102CA17", + width: 11, + height: 4, + isRevealed: rotate([ + [false, false, false, false, false, ...Array(6).fill(true)], + [...Array(11).fill(true)], + [...Array(11).fill(true)], + [...Array(6).fill(true), ...Array(5).fill(false)], + ]), + isFlagged: rotate([ + [true, ...Array(10).fill(false)], + [...Array(11).fill(false)], + [...Array(11).fill(false)], + [...Array(11).fill(false)], + ]), + finished: 1, + started: 1, + stage: 420, + lastClick: [2, 2], + mines: rotate([ + [false, false, false, false, false, ...Array(6).fill(true)], + [...Array(8).fill(false), true, false, true], + [false, false, ...Array(9).fill(true)], + [...Array(11).fill(false)], + ]), + minesCount: 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, + isQuestionMark: rotate([ + [...Array(11).fill(false)], + [...Array(11).fill(false)], + [...Array(11).fill(false)], + [...Array(11).fill(false)], + ]), +}; diff --git a/shared/user-settings.ts b/shared/user-settings.ts index 60e23ee..6f114e9 100644 --- a/shared/user-settings.ts +++ b/shared/user-settings.ts @@ -5,9 +5,5 @@ export const userSettings = z.object({ longPressOnDesktop: z.boolean().default(false), }); -export const getDefaultSettings = () => { - return userSettings.parse({}); -}; - export type UserSettings = z.infer; export type UserSettingsInput = z.input; diff --git a/src/Shell.tsx b/src/Shell.tsx index 587fd36..c72aa08 100644 --- a/src/Shell.tsx +++ b/src/Shell.tsx @@ -95,7 +95,7 @@ const Shell: React.FC = ({ children }) => { transition={{ type: "tween" }} layout /> - +
{children} diff --git a/src/components/Board.tsx b/src/components/Board.tsx index 3f969c9..553ff07 100644 --- a/src/components/Board.tsx +++ b/src/components/Board.tsx @@ -26,6 +26,16 @@ import { Button } from "./Button"; import { Maximize2, Minimize2, RotateCcw } from "lucide-react"; import useSound from "use-sound"; import explosion from "../sound/explosion.mp3"; +import "@pixi/canvas-display"; +import "@pixi/canvas-extract"; +import "@pixi/canvas-graphics"; +import "@pixi/canvas-mesh"; +import "@pixi/canvas-particle-container"; +import "@pixi/canvas-prepare"; +import "@pixi/canvas-renderer"; +import "@pixi/canvas-sprite-tiling"; +import "@pixi/canvas-sprite"; +import "@pixi/canvas-text"; interface BoardProps { theme: Theme; @@ -33,6 +43,8 @@ interface BoardProps { onLeftClick: (x: number, y: number) => void; onRightClick: (x: number, y: number) => void; restartGame: () => void; + width?: number; + height?: number; } interface ViewportInfo { @@ -88,7 +100,7 @@ const Board: React.FC = (props) => { }); }, []); useEffect(() => { - setTimeout(() => { + setInterval(() => { if (viewportRef.current) onViewportChange(viewportRef.current); }, 200); }, [game.width, game.height, onViewportChange]); @@ -113,14 +125,25 @@ const Board: React.FC = (props) => { const viewportRef = useRef(null); const [zenMode, setZenMode] = useState(false); + useEffect(() => { + if (ref.current) { + ref.current.addEventListener("wheel", (e) => { + e.preventDefault(); + }); + } + }, [ref]); return (
@@ -135,7 +158,7 @@ const Board: React.FC = (props) => { onClick={() => setZenMode(!zenMode)} size="sm" > - {!zenMode ? ( + {props.width || props.height ? undefined : !zenMode ? ( ) : ( @@ -152,7 +175,7 @@ const Board: React.FC = (props) => {
{theme && ( = (props) => { worldHeight={boardHeight} width={width} height={height} - clamp={{ - left: -theme.size, - right: boardWidth + theme.size, - top: -theme.size, - bottom: boardHeight + theme.size, - }} + clamp={ + props.width || props.height + ? { left: 0, right: boardWidth, top: 0, bottom: boardHeight } + : { + left: -theme.size, + right: boardWidth + theme.size, + top: -theme.size, + bottom: boardHeight + theme.size, + } + } clampZoom={{ minScale: 1, }} @@ -204,7 +231,7 @@ const Board: React.FC = (props) => { )}
- + {!props.width && !props.height && }
); }; diff --git a/src/components/pixi/PixiViewport.tsx b/src/components/pixi/PixiViewport.tsx index 6ca428a..2822e25 100644 --- a/src/components/pixi/PixiViewport.tsx +++ b/src/components/pixi/PixiViewport.tsx @@ -1,5 +1,5 @@ import React from "react"; -import * as PIXI from "pixi.js"; +import type { Application } from "pixi.js"; import { IClampZoomOptions, Viewport as PixiViewport } from "pixi-viewport"; import { PixiComponent, useApp } from "@pixi/react"; import { BaseTexture, SCALE_MODES } from "pixi.js"; @@ -23,7 +23,7 @@ export interface ViewportProps { } export interface PixiComponentViewportProps extends ViewportProps { - app: PIXI.Application; + app: Application; } const PixiComponentViewport = PixiComponent("Viewport", { diff --git a/src/hooks.ts b/src/hooks.ts index 0ecb0ae..aacdcfa 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -9,7 +9,7 @@ import { } from "@tanstack/react-query"; import { Routes } from "../backend/router"; import { wsClient } from "./wsClient"; -import { z } from "zod"; +import type { z } from "zod"; export const useWSQuery = < TController extends keyof Routes, diff --git a/src/main.tsx b/src/main.tsx index 56d230d..9a15b60 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -11,6 +11,7 @@ import { queryClient } from "./queryClient.ts"; import Home from "./views/home/Home.tsx"; import Settings from "./views/settings/Settings.tsx"; import MatchHistory from "./views/match-history/MatchHistory.tsx"; +import Collection from "./views/collection/Collection.tsx"; const setup = async () => { const token = localStorage.getItem("loginToken"); @@ -38,6 +39,7 @@ setup().then(() => { + diff --git a/src/views/collection/Collection.tsx b/src/views/collection/Collection.tsx new file mode 100644 index 0000000..363193e --- /dev/null +++ b/src/views/collection/Collection.tsx @@ -0,0 +1,29 @@ +import { testBoard } from "../../../shared/testBoard"; +import Board from "../../components/Board"; +import { themes } from "../../themes"; + +const Collection = () => { + return ( +
+

Collection

+
+ {themes.map((theme) => ( +
+

{theme.name}

+ {}} + restartGame={() => {}} + onRightClick={() => {}} + width={11 * 32} + height={4 * 32} + /> +
+ ))} +
+
+ ); +}; + +export default Collection;