From ce3cb00fcc01af5528d837d43d9ca43b2964e223 Mon Sep 17 00:00:00 2001 From: songyc macbook Date: Thu, 9 Jul 2026 22:52:11 +0900 Subject: [PATCH] feat(main): add 'view statistics' to action long-press menu - Add 'View Statistics' option to the context menu when long-pressing an action icon in the main tab - Route the user directly to the independent Statistics tab upon selection - Automatically apply the selected action as a filter when entering the Statistics tab, mirroring the 'View Records' behavior --- .../UserInterfaceState.xcuserstate | Bin 23482 -> 23682 bytes myApp/Haru_Danim/IOS/ContentView.swift | 19 +++++++++++-- myApp/Haru_Danim/IOS/Localizable.xcstrings | 3 ++ myApp/Haru_Danim/IOS/Views/MainView.swift | 26 ++++++++++++++++++ myApp/Haru_Danim/IOS/Views/StatsTabView.swift | 14 ++++++++++ 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/myApp/Haru_Danim/Haru_Danim.xcodeproj/project.xcworkspace/xcuserdata/ceuak.xcuserdatad/UserInterfaceState.xcuserstate b/myApp/Haru_Danim/Haru_Danim.xcodeproj/project.xcworkspace/xcuserdata/ceuak.xcuserdatad/UserInterfaceState.xcuserstate index 403280e935e5378f7ce500f8bd2ee606ed651faa..1aa384bd47cd9918f11a966cfb27b4a162b98e3b 100644 GIT binary patch delta 11342 zcmbt)2Ut^A`1d_`oPex^5g-XBtT3_&Ap=Mx30s3&ao|K0L>!=id*mMXs_VL~Rlq%K z(OPTWTKBHjT6fjf(W-USRsBwawEAzK=lj0rZ=T$6&pqedbKdv&`Q$9(5&;wAA8P=E$}AOIntDUbpghyt<13lIlXKn)Us4kUvV&-SI&>D0H zMW6@h35r1p=mknaZ%_%UKs6WyhJmSIHdqLjfEus@tN|N9J=g-afv>@Ka0Z+O=fL;i zJh%XU02jfJ;F1&k1g?QQ;1}>Kcmy7UKfoLC7kCTakrWBZCZrb`Kn9XQq>v0ILr57J zPDYTCWE2@oDo8DvNE%5SX(!Xk3^J3u zM=hsTP%Ejm)JAF(RZs1pzNJo6XQ;E(IqG}rJavKkfx1ZjL|vn9Qa@9-s9&kysfSML z59%rPjCx4}nxP>rqoZgAt)x}7o;J`%I*qo{Ho67fiq5Bd(#3QM-HR@zd(&lfAG(sR zqO0ja^k8}(EKGn}mcshEP|!5H!OqwVHF$#5gY@@!f|jK{1i@yv*BF004{?yuokX_YvBgC z9ex9Mz;EGBxCics-@zmB8oUl~z?<-A*y0wv4e!8T;IHs5ya(^Y2k}giPW%@;P<9tyHuW3`1tQ#D z3?v||Q*Lodd39N@vXaVn?s2gBY+JS+#|oNK;UI#m5rk8b1dD&Aof{iQ133s|JFo?8 zyLPU5S2aF}CvM;eomdCkEXv#=FVt@Of9hBH{-v=XK~FmUY~?D0 zTX*~h93+Hm!4B{(*a>!l-Cz&c3-*Ei-~fx*G3;1&96O$!z)oZ*v6I;;Yq3KP5psMz z3XXx}`1d3s$BvoG`r+#g_H%YA{#}OeqPfkna;|$w7&j+Y3Z&fLgdpy>*!JArkg>U! zU2eI;PGeIW%y!*nwj1E4>&t%1PIrG(`NQ~zMwr|M4+vo`xCidDGuc_S;5YC)JDXj^ zJv8RZz!UH%A*=&W!87oj<=8pw+&b_AyacbUWFTJiZ+GuZG^p3VIxN|klDuaq2T=exy$q)Dbdwo|*@j9QW=*s~-iJ?Zi9_7&IP z-alNCet!GZCnx?SpHF4yM_P-Q5w3sl$4+{aeneMcE$Ku0vWwZzYDqq^mtDf9u+iO$ zD|!y=QCO(<(f6}!5I)Ua!~_%MlHN1UuB zlSnyN+GYZm1(Igq%!cH)6ML;{Nn&E+eza7XPZ`z?E9E zn{lNtxgx%_RpYDMk{t=(TNC!7hGG1Oyjv|z+$wA~`atJw;97YZ&N01}g-RvHAFT0Q3&mLe8vftIe3|k0- z8~dI~&UTq<7JImcznX5qO*gS8ann<5^glL;w9XPc+>HzQ{tfmhbXlrxh1*PApzK-bajfq? z2%K_VP9ty@f%^!&LZq-hBD?}9CX-Ldr{pv8Io7k=>@VzH_P$G&{+12$wOb>GJsg_(_o3Wt*WY|I=!g6s9!}XcQwk)O$*lRsW2)W3p~}7 zl2S7E3HyxwvyO_OBB?0$CHsnf%_=^a02Swcps^r@ zO8vN?8I|^Nft|`El(kekmBIeSzN@9OsB8rA>J$Ec0)htRrX22}zWu-jLI0Th6W2oo zh=1(OcQ!DaYD;w|lu^l8&!w^i2#KFjR1oHM1Y5Y2Lhf5 zG(o@%0q=EGkxR{qD5`|&MU`UqL{WVRIRZWyg+4Ac2@nWFplJiXq_|X3$QR{T463Xj z89NBH8HS~t8jgVPdo8C%VJ)XdQ%=_x0Y3!z4Ocdm@6CseW}84w#zIC-q$VNYk3c{z zHHDgrKp+Ca+?ABv5NamHxhl*eeGv%4qDjpm_97tU)+B~SQ;Vq2F?p!P)MwNZ1VRu9 zML<+XEv1%W%mXn361VEJyj6rBwVEV3Lt1!~`Ddwh_;x+MElLYF&yUQTf z%^!Pi3$@Lyw$xW_4FWPOx6~Xq#Wjk@x{v~DC-oiH7HSu@o7zL|rS?(#sRPtO1R@ZK zL?8-*Xauk&V-Sc%AZ|5vh&oIip^j3=sN>WL>Ldd32q+OyA)rP;gFpfTNeJk4k*GAaB*&RN&no8s)o)UQIGMu z2$&JDG+Z%cd3@jZkfqhM7NddI(AZCD2v}?BL|TV{4S@_7WJR=zPIbY>mrh|nL%@#V zLR(yLN$0Go;sn}GXZ;6g>1;a31=>smve<=e^jX?L_|bV7q*GH}n5A3e+fVTASE=F6 z=Qoa}E!`PM&2&4uJ>7vWpgYo?5XeCw7lGyov_QatK;BBa3${r&qMYtd7a<&VV=}j5 zF)Z66(1G(-4&)XqW!wm5Q)gt_BcvXd_qtK#=)QEhYpVU|{s^>2;FDUqf*ycC8wB#% z=q|-&RXr>5R;#?Iyt+&8imGZyMNb@NR+P8xhhxoxvhwtz^1($_jbj}`43H3zr_fXBY4oQEbVi^H z0$ma4ww#_p&!lJ3vk}0u*Bt>o=YHG<)oDAuh+f=)+6Dl8?(+Xq1bVQk-_x~t6NI-y zbRE5%UO}(ySXI)mq^D~#2$UdDj6hEW`eM}PDTsuVq-*I782j`(dOZTY z5GbvsH`1FB=#4-hu9+s-bBpUeTM;PZx@qF5Z|EJ|W{r%gqratha+@?(=Wcq>M`WV+ z)5l$cl1{y$r1T*w15Cz?pUh1x_89`@>^r=CKVkn|O`o7o(x>Rt^cngreUAPf0qmWL z2+TlWCIWakUm$Q4fny(Y@W%!YR^Vm17v86F#r~$orMZ!km+4>sHXOO`7FoOT!9OKUfxHvZqf#Gh>F~Ni%6M{)*Qn)zB zi1Doi-}Y35I~zI2NSO%N%Ve$;#u3Ib3I7naBc|$yM8zz{ zT+Lg_Xo)CB$0T8@V$eEWL}d{e>*8t$F5Dd8OkpgpSEn*qn-BtH{vY|+IEV}eD^CrB zC1%`zGO)2;3#O%;dQ6^+dJ{19m`Im^fl=Hi$)Vb|j4O`+Pwp|D=$T9x7xyN)xi=Ye z4@Y>&BJAtt98-k3!1O?1$_JcdN|;_Q&LJ=j0lfITnASkDL7nRw$JCc8|CnS<1%ttk zsXzU_pfgo}^UP_HIfpXCK4KL!l9_}t&5UA3GfswO5Hp4u%Zy{jGZPq0nOO+nQF92) zL0~Qd^AMPizybsoBCrU7#p{^K4VY#=rFt~(RnK4!EYXGQ{^r2<%=wRvdy)C60Wz0d zkXiRZh=d2`yusZ2|A~;8`^*F8w+|zv4G3V1U{O_n7$G$}{#j#;k+c41@?^8-IyFJpx-0z)JlU0^1Py8iDNy ze6tpMG`JpmH>5fs-{trnjgH^hknBL5?rYoQ9_neIX0JC}aNKpiw<&%z|Ahj`Pp7Xj?w{dM3KOok~e zhUftV4&qFUuOgf)6m@o?m#A0&|fgAt#vEY%^ z!R2s8M?97)cg7Zh>)dI(!q_m9Rd6*9{{PuixU1B`Rd5Z#7T|4#`yMBL-M!#|!qrx% z*$C_L3II33FW_c~iSsi8w-C6Ez@6oA3)~97f|x$PAn+>!cM-V9C8q!2bQxt=!xRg8 zOn882aH(P5d)@GQjseSpAk2>gz~Lu3Sx5O|Eh9|$}_;OQDd4lfW<@B;i1UV=Zt%Q#o$ zhrlz}nu|lM=Lr0XzzYOk*6+>;1DfCA6W4?v!bk8i#9h2b;0*$QA@FuNdPx7xG0uj8*o|l9(=rbo)*U~c$i9_ir0jv z;U%~S>xW1_9xoyVi1c5{O9XOW5>Jm$B;<$;U<(i#h{zzE%qwusAR;#-(}rW|!DZFM z+HfNr{#WU^ zSeTYfYkU^hmTAuvFrAn#OgDTcHpLgBGXI;NJF(4kpC-51zj~Ls=&TG#r;|=Cb<}Kx|=WXR}<89~d z;O*pn$2-hB$~(?G$ve$^;=%I>^+@w@c(n8A;L*{evqx8tULL(Y`grv7DEAoPG0|hO z#}8|)V=Y-EmpVLmCAAN54-0^wn^T_89pVz)kd*P1UkMmpRx5e*}-x0rKekc4c_}%pT#qSB9z-M+OpXNipl%L4A@jLRJ{rHpkQ~1;P z)A=*`v-xxQ-|}Toc^zxA zN7!8G5VjO{7IqaD3X6p0!ok8Z!g0b0!b!qg!rz2XgfD`9gPR4n2<{%-Be*!YS8(s( zKEeHh%Yz35R|Z!HPY#~y4E{8DM)0g)E_iP6{NRPbi-VU0FAd%wd_DMGNO(wQNZ*hd zAsa(Zgxm{x67oFcMaZjAD%3mFH zYD6nVt3_)?n?##M^`fn!1ESNSbE3hABRQguNlSyQ8GNnu{)5>%*y)0kWT~;D1m6gfLWdmfD zvTE5h*+!>qhwOsvqU@6Fvh1qty6mRxmh6t~SJ^$;1KIDgN8w)KKH+}h{^5b)!tl^= zad^}4@bIYcnDF>;Ww<&#H@sJPRrsRtec|7S-;3Zyh$9jsN+O0tOpll!Q5&&5Vr9hY zh_w;xBQ{3th}apiJ7RBSP-H}8RHQsIHgZJdq{u0e&S{a;Bdj_w=XKe{4%V02Y9 z8$Bj^T=azKi_y2Ee~G>ueP3>oH|U*k-YvV~59n9=j*@R$P-f zeO$-5p>gx$w#4m>+Y`4x?qJ->xF6y!#a)TJ9`|$H?KtNzad+dM$Gwhw8xP`Pyl1?3 zyl=cBzGZyp`0nvN<4fZE#P^S{h#wfw#*dAk89zUMQT&qlW$~-x*T!#%-xR+&{*uC5 zp;8zW>5BG>0!5LcT!9p071I<86^j&$6-yLr6`K^B66qgmhDIO`F zD4r``D&9C1@06sHQ3{ozN{Ldcj8H}^W0eY}TA841u57O?Q;t*4R<2NPQyx^FRGw0v zRsN*>Rryf)O!-#%PDQFBR0@?zm8?opnN_(ehpLsTjjElhgQ`qbsj5;9RykGURJE#2 zsxMTVRrRVps)MRSs-vn?sg8d~G2@z(fh1RAyG6HPZwPfdxYx2C_QLQ|=!){NCm&~Q%8BFz%b zGEJRkt!9Jf3(c3BEt;L0qnaz4Ynop*&k{Tmnj{1#L?y%|#3!f{5)yO?hJ^Hltc09| z772L?trPMS+9mW!n4GXOVPC>6Evfa=hG@gIGHs+bR;$pewFz2_wz;;Iwm@5=?XB&r zE!PgzR%u!76zx>)0__s5bE&pgyGpx8yI#9dyHk5qdro^n`=j=<_L}xr?S1X<+Q-_b z+UJSUiLDYxC$37|nRqnuSmN=-lZihhUP`=@crEc!;;Y2JbcBx5L0v~(4_$?>S~o;D zT<6q{(T&$l)XmV%(=FB2>Q?Ah>Aut*)}7Hk*1bpyNm3`JCYh5g&ZM*?M^e|M!lWKa z#Yv?}Wl4RL`X^N+u}Nc-CL~QxnwB&pX?D`wqyQ(v#y-sh? zC+p4nG`(G)sn5~3(6`i==zHt?==wnN+(qGoUGe`_^h6IDoU@#;btcG+$mLbQ` z+>meRZm2R0GK@A%HGFPZX4qi((y-OA&G4;Zw_&egzu~Omyy2$dq2Uk1Gs6qRYr|V3 zF!~w=#sH(x7-|$7n;K=tIHSRsYHVh-8MBPJMu*eb(%9M9+c?NL)HuR8+K7x}jWdl) zjJ3w)##P4k#*N0!#(LvE<0<1s<4?w`#v8_4#@~#Oj8BZujW3O_O#+k16lRi{B1}4y z!IW$=o6<}+cQ(sem(_qsu(@4{3(;QQcsn%3yT4DOqbi{PrbjsvB zYdUYbX!^-?)pWyj%k+!sUNT6glVP$)a+74AWPWl$a!_(`vM5=S+%!2gxl{7!dbSxQ~Xij<8h+fuft>`2*}vO8sO%E^>-DHl?HOu3qJBjr}g zom47So~lbVrKYA@QthdksoANysRgMe&eVRX6{(e}gHlJPI#b7_j!T`8x+(RBnKXNu zL(B@Z%4{&Fo7Z#REy-fiAzK4?B{ zK4v~?K4ZRVzHR>1eBb=L`LX$_`A_pJ^BW6effi4Tza_vTv=}VumI6y>i?f@h$Wm-6 zwe+#{w+ygUSq59CTBciOT4r13Sms+6S{7TDSe998Ez2!?E!UgT&E(CRHyhAwPP6)E zXPZ52_M+MAW^dDoG|x2uw7@iBT1c8GO_COurcTqQC8Z^&nbXqJY-z=5C~bP$+_VL0 zi_<<&TamUZZEf0yv`uNJ(_T8Q3Tu+pW^HS2Z!NU;vpTKFI^D`y=UNw7mspotYpiwF zFRi<+2dv*&k62GyPg~DgzqkHuePn%X{logy25h8_vN1M)TaYcpCbl)T$!uzy-PXd^ z($?D6##U(SVJo(k+WOe~*#_B$+J@Uk+9um(+Bn-h+d|tio3qZg(zeF7&UV~R+g0`y zdz#&D&$KtU=h<7^+t_>A2ik|*$JnRZr`zY-KeyM}*W0(+zqTK=AGM#bpSGX3U$p;Z zzhZxEf0NFn`=$G*Thg=A3(^bId#4XfuTEc@zCL|x`q$|@(s!lrO+T7`BK>swx%3O^ z7c+u0+GemB>zo-|GInO{$vBd6HsgH8)r?;qg|8Ic*C8JnrdRA*{4 zlQNB&DVcehtuotWw$1F2*(tMYX7|jVnI)N}nU$H7Gix)qW**PHk$FFh%93P7XLZWz zp4C5VXx8|w=~=U~=48#!T9j3nwK8i>*7~eXS(~$tX5G#vvYoo@tLV$0A3KW20k-W0zyEAS{7E5)uLgvIhtt0`3d0h>D6LsG!wq&5TR6TGzB{ zTQ|Vn)}?OM+QnLzZno9d+E#6CU8+^9wQ8-l{*xfBe*M1Z|9|q_d%1IGIdjf?-g9PV z+Fr144_H_Q!WRu*>b=9wK%2u<(*x~GG zwvKIJpJAu6UiLY54m+1!#ja+X*k-nc4PC>oW!JIm*$wQg>^2`{3%%)_iOb}2xLnT8 zIk-G7pDW^uxl*o-8^#UiMsPLUNNyBY%Z=vhxO#33Hhj&dJxA95dYA9KgK6WkZvY3>Yn znY+UM?B%X<*SPE4uiPE(0rw~O7er71gP;(GLJ{QxzGZw&<5?$0iDnV z-OvL|VRzUA_JjlAKv)TD;7B+M*1|Ec5l(~{68Iuq0++&N@Fn;%d<8CtE8uFl2Cj!2 z;70fw+yQq&?;f}p?t^c`lkh8e3Vsd0f#1T@@C-Z)zk}by^YCYQ3;qUg!-qV>1D@p( z-;NLC!}%Cq!K-);uj7q;F5ivs#Sh>I@|FB>egt2`kLAbl4g51a;b-zM@=N%Y{3?Dm zzm8weZ{@e~`}w!{1N>qB2>+>t)StuKo zpfc1MbwRyQZ&ZQ$qrqqx8iU57ai{@JMpMu;h@cs07FvK7qDAOM^b%T*HlU4Y6WWYk zMO)G9Xcu||9Ydd@&(P=SI68s8KwqMhsNgGf3Vn^fLEoa&=qGd;T|qyitLPfKj($P6 z(L(_v00LIP37|kE5DO#%nIKZ25u^&z1X_Vkpcfbg89NrjK0*9<7eD=G@{a4mr$Is~ zF2fbL53a-8@hA8g{tRmemRC)z8C~;q_0aB(RgKlYl_Eo!)Kfip{P5w`VE5yi(y7zuNN31vi#nE9RggV8lH_i%X=b02r|t%`{;GY^?# z&42*_cg8)j<55)rK@cNv0X#rJfV<$XxLXSdW|Bb&?vBN{hwnyAM->PM5&xDJ8Wb!*M@65|74xajEYGNv=cB99;v_ zfdLpn2JVjs;UTyh+fINikWJg0K@Q06TQan|uCZoVP4&2*C3QoqC*lEkAg-*Gg!?|1 zhx-)LAkGdPzEWu%*9@G#5^18hwY3}Mfm~dL2jj|~enmA%D511|Dq_yjPeXAjuIygY zxqDl2X`pzRzqoIQs&V5hJymrzqfdY?RFf@^nQ^@*({$N1gF;$Htx;KuisT+=K z@hIPdux_$JpsJszSC1mvvJ3s%0tSO2zT08RTs0Wxiw)O<;l8r)%;Fm6SQ8kD>;Ey> zXwb;$)`2=u55|D8U>s<`WAIo!4maRNJboRM1SWu|=x-8}ghTNJ{1p97^c@bL8#fa? z$LLzXvtSmOjVIx!@#GdT2h0V}<0*Ix-sT%4D>E!+jy3@weg@mV21~$FunfEeUZ#3@ z1uO?EsAX1x)u4&CX#s1%TCmRdv+R&}0G^HK;Hk8at@t%O6F>JP6gGg3tx#aj;ThQ5 z2882&q=Kz}By0oQ!RufL#+cw~c=~@Jq1Eth#(K=WkBVI2F}t=^d(5U!7_!x5C%}hv z?2kYX@Ci8PtCL4?v+%RNbJD@W&%yDYow`#iH-pc8cjR6AoCN0>`6locI0e22-+*ty zX>bOd1>b@1@m%~oo`>h-1$ZG|gcoBUeqj@nMBU;%HNr)33H(H#SD0jK1~Gn--e1BS z@J9OFMBmlE_(+*=z9!6f&=KczYm`0^`Af;~e)ZqOOR%j~JrDfq`4jx*zwlDLEO6N* z($<#_1|U|u>$-uex;cWX4~QAc(qS#D5+${Y?%L}gq7kIcx5wlfR$k@UWL{D zYHRAM18!B_Ft82VWz}`V8%IdZx7+%TW@D+_voWlKRpKVxj9XgRI9A2R<2864UhmtQ z=Jm2EjF{E1sr@^3Pai+NX6WEajnxgEC6c7?)@Hz)?q6502%3NNm3ag3+T+X=<{4JY z>UvQH_bl-=vswlpXVYnW!@t`nT#Ic0IJj%qMRun!H%Rn&(`4mP3$QA7Ug+`x1Q2GJBA&L-^K_2 zW(~HHo%o*&&Q4;I*~$1F3dVP_`frI7-Ltj@)Y~QuW@r4X=}g*m7JiR5J&4u+$e-w5 zoHhH2#?P}aGP(`yJa#_2fL+KgVi&VM_62+hAI3-UQTze^5PyU}-mzQx5=f|>aQA z(yzT9^#Qe{bRpUeG50cJ_5f zw|X_!`V^|$QAa7whZ69S|MoEf#|XGYz#YPd?MRES2gz&MTkLP_ZT1f3u?zSTzKnnN z)6w5_!QRIVp5=Qdp+fd|8OQj`@K2SJF23zqMZV6N?WB)2;rKw4=M#I0|7p@LPYt)QoOD7t6(Q zDlVQ&0BgAt)9k}bA1@yX08+0nd`!J<+^d*xgK0kt{2yvs~~_O0QmIT zF~-eYUnZHlMG`lVtK$M8A%ba1sHj1f==88^N2i+fMm`) zeZqap$eTFonc61qGXiw9kH?$&a7MfMw#r{}rvkjseT6p@kWLlEHDhZ)NjZ@w?kx8s zB~tD??tAVW_X7b&0x}3N5s3u$)9{m$Lv{^0KSX{fHP9^#)L0d#B&0l5UY|8W~h(fEEX zZ4y6(ETe0N3bz`dbNhCz|b(54h`E8n&qy|Oy$H- z;`=-^ftSKC2GjpkzR0XtuMDQPV$V__Ur!FZSe6JZim!(>Pe z~4mC?%kbfN}ylZHB3>eg^eiB{cZ`44V9Y*16TsC_uXg9Bn|W zqYZrIXs?yRJiqjmdb&LFG)P108rnhNM{BqK+CnTWgPo~CVL9wXKsN%qH^VNFcHM)3 z-ZZD_7|{#%@qh2__lcg=CtzQ{PxSKpgb$~+Q^P@UDD^;C1qZ_+1W>Z*LqOjaSPh5y zJ+L1E{aZ7aAUK*4!#e77A$GqD!m;#q9DOz0<1^b_5RQivo>b!`I3)l$IN1-lN(wmG z*AF-U=#th1dJwt!l|AB%2JKKblvh?xDu{fO~A-N_=8QbndV&O;~T36 z*H(A0Zfv0?EexjFD}8AN&f3=cKDk3RDA8T}Zh$S?0I~^gesX48AZ3pxNI7Fn6WmU~ zSgfs-h^r@#siMoTq5gEK#M98)@h-TV3No%$kQVqxGi>oq)2Ddhn{fY=oxTG8zxWY#4PGZ; zIsr49;SG3`fSCl$4RAWV1OMMr~p-Xq{y0%j2~y9M57 zINw&A$$OmV7%>n3oz(u9q?i}bszLv*`tSVrk-U5eFQW4DLca$*Pd$K@(Z?#h4XYnz z^1gjJl1Ld(m+Ukl=H-5z&Tj_K)7*a>UPWOVrPne01=aVQYaY>vC|B3H5^J<3C&CV*+?^=%~MW&fq>2bbYkHPDG4e5Z*kqb znJ;QJKi`q7-~KbG1%a1x&szpR z74g&P>va11lOf*QMn(Ly{Jejn`&Js=UwbUNCj_FqY8^kHYHA_Bh}*?b_Gs}(_ca7i zgr?#oto_f(%`fF&_D_2mPu01WfOY?l-0A-{bhpi~iEp8?nr|jxLu;(|k(`LA4gBU- z>}~R6Z__`j@`Ep9JHPvX#bkaDcY)vQkIAnFVlthfKPFGjm3v#Q`?lY@?+~!%u_(;H z#~<`ZVFI=hK-tS5dlU1H{5AahhTa$31U<@s^kmfKKjuFnfYRLSZOHk|PaFO)i*0n5 zDUbwZcCQ&;M|W)shx!)g3JbsFPqhL(fdc$~GygUJ4FNj|pbNgXanA6U{~z*Jif_6v z;Llt6>lEKN0{Fh=$M>!_eD4k5`#>wc{R^!}_`d7c!0!a?enf8keLub*@PGO*0`?H_ zM(ds8TPQ(~Qu#6N)>BllP%DVw9qj*M)68v#g>&G%u)7NDBTBZFbtfEx(B$*&RG6o=n41UNQ zq>yO~t4;1GuNk@if1)aKqdb)VcvL+^z+nQ8{6|!Mq*K(fEv|~FtmUmQl@eu1en~-K z>E%ms#Dt-)s5`|vqDjdIO^7nghrZanw5mST9*h*Te{T|?0jScy`AW;0&>#XnX&Yq- z-O3BpY}2y=ZLwB2-(KNa#6KF9L;YT&U%i?L(HYm+TG{tE~&mr3WYXZJ$M$e;p z1bj=tnI~lNrRT|IVze0f&fqjHCkx#G6q-B zL?-ZloJ#NSy3#-Wz)ZIV3jZ3B-|NVMzYBM?77n+|KV1BG;qEq_ zJmv2Fm`e5{x&YdU_Mtb?e)JZ48@+?xMF-G(1pGw6Wdg1c@H5E)R|&XA08KM~A>hVF zCK(;_U+5_M0DXvPzJtXC+zi|Z_?3WL1pG$8?Hxl3mB4TY{otSQS@a$H9?^N;C4jQP zJp%q%gMLKk(FJso0Lp<62%t3Zmv3v)vI2C2Io5)1qF)j1>LFoyLN^EhM&BJo4+&b( zUGzJ;M_7iifUs-}x{n^99|_A57SaxVbBdR_c|q`hsVQhD2oVSgiwG+qY)~M&w5~^o zFe)|6sE!Myj93sR2;VWdLlpD|2e2k+FOU!T+u{^*RV}nAg2Al-ta^kpL6ks6qaC^{ zh!H5zJwdD>E+AtFVd;=8VM7TkS|^AHd4fbi637F2gcak#gt8ai>>NygG$~A=J8yY( zT{fYnaZ)#5TzQyJSU%ei13~&DJ8rsdMAVM;5((3Tsb_{VRm>ztMemLDp37L7OvbD- zFkP7PK>QJym}9H4g9&1ym;^@0WY8KerYqBn>CX(Lss4O=bk+j5z+Lp5Y(G6IJ4n;r zBk%)wgBS2JnpCCGEXu3p^}K=4;4^80RK$1SJMv|GC%y|k80$fg#wz$RyqDj~pF&Z{ zMo+N(r&iQ~P!rmTcGGjIeH3ADQ*^zD-baV&an!fy428rwih&F061q%}q^{9}sBl4w zz$)k@s1no(h+wH;jo>xGR>5|`4#6(3;BCRXg7*aP3l0m83Vs$m43Y-r1bKqWgE|Lw z4eB1$GiYGYprFA)LxY9|jR^7v`GQ^zIui6n(3e3cgH8pV3%VL~JD3d?1WSUo!MVY< zU`Mb!I6v4ETpm0!xHh=1-Q0FBw0o=F`|YlUbPMShGB#vl$jXq-A=^S;57`;AH{{I_ z?^_}7gj^B|g;Bx;VUjRes1c?KGlkj09HB*M6FP()g{8tWVJBgYaDs4>aI$c!5DTXX z=L+Wu7le93%R~EyR)$uE4hbC*Ix@62v@Ud6=>E_{p@&0{hJGIUb?Dj9OQAo7UJ1P= zVnxBCFj1T+OJo-1imW2L$SHD*^1ULDs7Ta7G(c1-suB$mRf~p;YDA+%qebb}Q_GH(U@N93B$hJA6=hZFobtH+)g}%i)K@KMcPe{+A5MI2kVslf}v6 zWr;GiEJcyXR+(Mql(}X3GLNiCHcU27_Ka+)Y>b|5bbMH93%n%C&O6+#t`8XUenX zIdY5KCU?kt$t&c2<^AOY<%8sd<)h?{@(J>Z@~7of zY{d5wKX@a~M_i2fDdI}R)rjj6HzN5+L1b`bNMvZFI8quJ9@#!JA~Gs6Cejr-FmiI_ zipT?zm!d+V(xOVDhDFs!jf-lGnh@oUnjJMK>iMYoQ46CMN4*fWB&sE9L)50ISEIH^ z?TFeHwI}L}sJqcHIygEcIy5>gS{5yjj*L!<&WtukdkdmFMwdl*itZBKJGxJFzvuzc zmC>`K_eFmjeLnhT42(fB;uv{MOiWTtMvNz>D5i5vMNHqA;W4!_bunXN#>YGrGbv_r z42fA7^J2{Ym_sqAW6s6=t^f*F0Toh3v_heXRj3pR3avt~Feowtj#Gfw+vg zA#sc2*2nFPI~wZIzF>KoN*)mhc|svlJ6RTou1#dGm|ydb`vH(nSo zikHTR$IIiR;uZ06@d@!s@yYRd@dM*W#V?NE7yohm5AhEZ!V}UG1|-xcJe#l};pK$o z2`dv;Cp0IlNm!S#BVkvPmH$dWgDOJzQO*9;F_w zo}!+rCh8gLS?W3JdFqAg#p+e+CUuK?t@>UvN)AeHmn=-KOs-9?OCFOvF8TfB&y!Ci zf0_JMiYdjFl9y7DQkb$dWlhSulnp7HQXXi6H7ZS_CRvlJ(P<1ClO|h}tFd`CPEDSs zLeoz(KvSuy(hSuM*NoKEYU(s&H4U2an#G#!nlCkXQ)5!|QfpHerfy9=milw*Z>e`v z|44n1#;1wWq-nCWh_vW5MOti{DovkeO3O~mO>?BV(+biG(?+DtOk14xQrhygRcXy> z8`EA*+nTmLZAaQ^tw?Lo=4!o#+6rx7?GWu4?R4!-?PBdx?aSKb+9vH9?KLRuuiBG=@NDMx=P(--AlSRb?@sw*PYaT ztvjtdr#r8^q`R!Uqv!NOy;L8jkJBgU)q0IytJmwTdXK)VzL!^Dq3@?3q#vxW)(_WD z&`;MtuV0{Ftbb9zOy8tmqhGJzq<>AnRev@;C_N{AQ2K=Q>FG1lXQt0eUzqMoUy{Bo zePjBL^xf%u)Ay&pV+b?E7&HdG!Dz@dC~G7!TY!zROa z!{>%ehTjag4cCIf6`9kK3%uShZWxkX7apotP$1*?5Jd^oD z=K0J^nO8HfXWq=bmBnU>vs77$S;<+cS-LDkmMJScD>thot1PQ?R=2F4Sru9RvIb^V zWqF5WJ(KlZ*7B@9S%dsKF9_UP>T z>?zsa>}lCEvu9_|$zGnlHhW$6#_ZR#_hf&W{X_PT+2^w_X5TUgnM2GXv(zjzN0_6{ zO0&wGXihfU%uci0oNxA+i_InGQggYvi`U%E+`~N9ywJSUeA4_!jw;8KGbCqP&Z?XZ zIh%8~A)f-GW-!eX#wSe%vuOOd66rQFil($&)4GT7p+ zw=`NNSSDGfTCioBWroFPS#4>uG+WkKwp(^v-mvVmykmLKa>#PT@`dF~%Sp>A%LU6t z%O%TY%N@&o%b%8qR%jJi+gXLyD67$$X*F9dR=d?@&9@d>J6KDtovdB0BdnvWqpkJU zvDQZGQ`V=gQ>;_1#5&zN(>mX4U1WX1y2QH5y1}~Hy2ZNPy3@Mb`i6C%^@#Oj>!;S^ z)~~GJSkG9$vp%rJ*>tuHTc*uyv)LRrw=Lh+)z-sSWgB4|WvjD|wN125woSER+ceu; z+cMi`+iSMnwu82lwo|qXwqI?xZNJ;@+y1fxJG4vfGP~R!Wmnj}arSt7qFraV*q!z~ zyT@K)FSB>HceM|+kFrm+Pqt6B6Z;JNvv!|-wSBF9y?v8?t9`qDr+v5mko~y*Tl-o2 zIs1A0CHoEgE&Cn&J^KUuUk;f==};uzr=<*0Lv zaZGYdad^EB;#lff9jjt&U~lGS?=uR?Bne3taJ``4s{N5j&P25 zKJ9$QiJdc@vz>FD^PHQUpE$p9e&_tbdEV*0?7Zr{?!4iA=n}fZU2<2HOW{g%CA(5x zT9@8sb``jKxhh;$t~wWSO?NGHEpjb(z2Itct#fT~ZFX&Qz3$rO+T%LxI^jC+y5zdz zy5_p!y5+j#y61Y}4s}c1;cmG*%B^t6xf9%KcZ%ES&TwbB9d4&P&t2uN^SZ~n8{JR2 zpLS1i&vCDGuXk^9zv|xNe$)N7`(5`z_hI)@_vh{}+$Y_q+!x$e-M_ehb>DVBa6imr z^Y}bLo+fWl-g9|N@?ObXnb(xJE^lMrt9e`U_U3((cQWs6-le=NdAIWZ$a|O{lrPPf z<;UkI=cnfD@-y7Qlo$|B05%amoRvc$6F zveYtjnWfBD<}AxAD<~^0D=w=oTU7RD*@d#}Wp~S&a;`kN+)!?8U23yz>r;@``fR(G GoBj`JS%Jv_ diff --git a/myApp/Haru_Danim/IOS/ContentView.swift b/myApp/Haru_Danim/IOS/ContentView.swift index e6df3ca..fa954a9 100644 --- a/myApp/Haru_Danim/IOS/ContentView.swift +++ b/myApp/Haru_Danim/IOS/ContentView.swift @@ -90,17 +90,30 @@ final class AppRouter { /// 기록 탭이 열릴 때 적용할 행동 필터 (기록 탭에서 소비 후 nil로 되돌림) var pendingHistoryActionID: PersistentIdentifier? + /// 통계 탭이 열릴 때 적용할 행동 필터 (통계 탭에서 소비 후 nil로 되돌림) + var pendingStatsActionID: PersistentIdentifier? + /// 더보기 탭 내부 내비게이션 경로. 더보기에 숨은 탭으로 바로 진입할 때 라우터가 채워 넣는다. var morePath: [AppTab] = [] /// 기록 탭으로 이동하며 행동 필터를 예약. 기록 탭이 노출 탭에 없으면 더보기 안의 기록 화면까지 바로 진입. func openHistory(filtering actionID: PersistentIdentifier, visibleTabsRaw: String) { pendingHistoryActionID = actionID + open(.history, visibleTabsRaw: visibleTabsRaw) + } + + /// 통계 탭으로 이동하며 행동 필터를 예약. 통계 탭이 노출 탭에 없으면 더보기 안의 통계 화면까지 바로 진입. + func openStats(filtering actionID: PersistentIdentifier, visibleTabsRaw: String) { + pendingStatsActionID = actionID + open(.stats, visibleTabsRaw: visibleTabsRaw) + } + + private func open(_ tab: AppTab, visibleTabsRaw: String) { let visible = AppTab.visibleTabs(from: visibleTabsRaw) - if visible.contains(.history) { - tabSelection = AppTab.history.rawValue + if visible.contains(tab) { + tabSelection = tab.rawValue } else { - morePath = [.history] + morePath = [tab] tabSelection = AppTab.moreTabValue } } diff --git a/myApp/Haru_Danim/IOS/Localizable.xcstrings b/myApp/Haru_Danim/IOS/Localizable.xcstrings index b8e31d7..925f239 100644 --- a/myApp/Haru_Danim/IOS/Localizable.xcstrings +++ b/myApp/Haru_Danim/IOS/Localizable.xcstrings @@ -591,6 +591,9 @@ }, "통계" : { + }, + "통계 보기" : { + }, "특정 시각 지정" : { diff --git a/myApp/Haru_Danim/IOS/Views/MainView.swift b/myApp/Haru_Danim/IOS/Views/MainView.swift index 2383cc3..d731c4e 100644 --- a/myApp/Haru_Danim/IOS/Views/MainView.swift +++ b/myApp/Haru_Danim/IOS/Views/MainView.swift @@ -99,6 +99,23 @@ struct MainView: View { } message: { action in Text("‘\(action.name)’ 행동을 삭제할까요? 기록도 함께 삭제됩니다.") } + #if DEBUG + // 검증용: -openStatsFor "행동이름" / -openHistoryFor "행동이름" → 롱프레스 메뉴와 동일한 라우팅 실행 + .onAppear { + if let name = UserDefaults.standard.string(forKey: "openStatsFor"), + let action = actions.first(where: { $0.name == name }) { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) { + router.openStats(filtering: action.persistentModelID, visibleTabsRaw: visibleTabsRaw) + } + } + if let name = UserDefaults.standard.string(forKey: "openHistoryFor"), + let action = actions.first(where: { $0.name == name }) { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) { + router.openHistory(filtering: action.persistentModelID, visibleTabsRaw: visibleTabsRaw) + } + } + } + #endif } // MARK: 현재 진행 중 영역 @@ -189,6 +206,15 @@ struct MainView: View { } label: { Label("기록 확인", systemImage: "list.bullet.rectangle") } + Button { + // 통계 탭으로 이동해 이 행동만 필터링된 상태로 표시 + router.openStats( + filtering: action.persistentModelID, + visibleTabsRaw: visibleTabsRaw + ) + } label: { + Label("통계 보기", systemImage: "chart.xyaxis.line") + } Button { recordsAction = action } label: { diff --git a/myApp/Haru_Danim/IOS/Views/StatsTabView.swift b/myApp/Haru_Danim/IOS/Views/StatsTabView.swift index 3880d4f..1082fb4 100644 --- a/myApp/Haru_Danim/IOS/Views/StatsTabView.swift +++ b/myApp/Haru_Danim/IOS/Views/StatsTabView.swift @@ -13,6 +13,7 @@ import SwiftData import Charts struct StatsTabView: View { + @Environment(AppRouter.self) private var router @Query private var sessions: [TimeSession] @Query private var entries: [CountEntry] @Query(sort: \Tag.sortOrder) private var tags: [Tag] @@ -112,6 +113,7 @@ struct StatsTabView: View { ) } .onAppear { + consumePendingFilter() #if DEBUG // 검증용: -excludeActions "이름,이름"으로 필터 상태 주입, -statShowFilter YES로 시트 표시 if let raw = UserDefaults.standard.string(forKey: "excludeActions") { @@ -125,6 +127,18 @@ struct StatsTabView: View { } #endif } + .onChange(of: router.pendingStatsActionID) { + consumePendingFilter() + } + } + + /// 모음 탭 '통계 보기'에서 예약한 행동 필터를 적용 (오늘 기준 기간으로 이동) + private func consumePendingFilter() { + guard let id = router.pendingStatsActionID else { return } + // 해당 행동만 남기고 모두 해제 + excludedActionIDs = Set(allActions.map(\.persistentModelID)).subtracting([id]) + anchorDayKey = math.dayKey(for: .now) + router.pendingStatsActionID = nil } // MARK: 기간 이동 헤더