From da6e9b6838910016bc7a40273e8806bbbf31893c Mon Sep 17 00:00:00 2001 From: Alexander Romanov Date: Sun, 19 May 2024 12:02:26 +0300 Subject: [PATCH] Fix tvOS support --- .github/workflows/ci-pull-request.yml | 19 +- .github/workflows/ci-push.yml | 17 +- AppExample/Example.xcodeproj/project.pbxproj | 14 +- .../UserInterfaceState.xcuserstate | Bin 98779 -> 222803 bytes AppExample/Example/ExampleApp.swift | 2 + .../CreateEventScreen/CreateEventView.swift | 792 +++++++++--------- .../CreateEventViewModel.swift | 306 +++---- .../CreateEventViewSheet.swift | 176 ++-- .../SaveForView/SaveForView.swift | 68 +- .../Pickers/AlertPicker.swift | 68 +- .../Pickers/CalendarPicker.swift | 88 +- .../Pickers/RepeatPicker.swift | 200 +++-- .../AttendeesList/AttendeesView.swift | 126 +-- .../AttendeesList/AttendeesViewModel.swift | 86 +- .../ContactsLists/ContactsListsView.swift | 128 +-- .../ContactsListsViewModel.swift | 78 +- .../ContactsPicker/EmailPickerView.swift | 341 ++++---- .../ContactsPicker/EmailPickerViewModel.swift | 86 +- .../MapCoordinateView/MapCoordinateView.swift | 12 +- .../LocalNotificationSetScreenViewModel.swift | 112 +-- .../LocalNotificationView.swift | 170 ++-- .../Model/LocalNotificationAlertsTimes.swift | 4 +- .../OversizePhotoKit/PhotoOptionsView.swift | 25 +- 23 files changed, 1500 insertions(+), 1418 deletions(-) diff --git a/.github/workflows/ci-pull-request.yml b/.github/workflows/ci-pull-request.yml index 4a45485..e2720f3 100644 --- a/.github/workflows/ci-pull-request.yml +++ b/.github/workflows/ci-pull-request.yml @@ -3,9 +3,6 @@ on: pull_request: branches: - main - push: - branches: - - develop workflow_dispatch: jobs: @@ -14,7 +11,15 @@ jobs: uses: oversizedev/GithubWorkflows/.github/workflows/build-swiftpm.yml@main strategy: matrix: - packages: [OversizeKit, OversizeCalendarKit, OversizeContactsKit, OversizeLocationKit, OversizeNoticeKit, OversizeNotificationKit, OversizeOnboardingKit, OversizePhotoKit] + packages: + - OversizeKit + - OversizeCalendarKit + - OversizeContactsKit + - OversizeLocationKit + - OversizeNoticeKit + - OversizeNotificationKit + - OversizeOnboardingKit + - OversizePhotoKit with: package: ${{ matrix.packages }} secrets: inherit @@ -25,7 +30,11 @@ jobs: uses: oversizedev/GithubWorkflows/.github/workflows/build-app.yml@main strategy: matrix: - destination: ['platform=iOS Simulator,name=iPhone 15 Pro,OS=17.2', 'platform=iOS Simulator,name=iPad Pro (12.9-inch) (6th generation),OS=17.2'] + destination: + - platform=iOS Simulator,name=iPhone 15 Pro,OS=17.5 + - platform=iOS Simulator,name=iPad Pro (12.9-inch) (6th generation),OS=17.5 + - platform=tvOS Simulator,name=Apple TV 4K (3rd generation) (at 1080p),OS=17.5 + - platform=watchOS Simulator,name=Apple Watch SE (44mm) (2nd generation),OS=10.5 with: path: AppExample/Example scheme: Example diff --git a/.github/workflows/ci-push.yml b/.github/workflows/ci-push.yml index 9b09524..cc427ce 100644 --- a/.github/workflows/ci-push.yml +++ b/.github/workflows/ci-push.yml @@ -8,13 +8,20 @@ on: workflow_dispatch: jobs: - build-swiftpm: name: Build SwiftPM uses: oversizedev/GithubWorkflows/.github/workflows/build-swiftpm.yml@main strategy: matrix: - packages: [OversizeKit, OversizeCalendarKit, OversizeContactsKit, OversizeLocationKit, OversizeNoticeKit, OversizeNotificationKit, OversizeOnboardingKit, OversizePhotoKit] + packages: + - OversizeKit + - OversizeCalendarKit + - OversizeContactsKit + - OversizeLocationKit + - OversizeNoticeKit + - OversizeNotificationKit + - OversizeOnboardingKit + - OversizePhotoKit with: package: ${{ matrix.packages }} secrets: inherit @@ -25,7 +32,11 @@ jobs: uses: oversizedev/GithubWorkflows/.github/workflows/build-app.yml@main strategy: matrix: - destination: ['platform=iOS Simulator,name=iPhone 15 Pro,OS=17.2', 'platform=iOS Simulator,name=iPad Pro (12.9-inch) (6th generation),OS=17.2'] + destination: + - platform=iOS Simulator,name=iPhone 15 Pro,OS=17.5 + - platform=iOS Simulator,name=iPad Pro (12.9-inch) (6th generation),OS=17.5 + - platform=tvOS Simulator,name=Apple TV 4K (3rd generation) (at 1080p),OS=17.5 + - platform=watchOS Simulator,name=Apple Watch SE (44mm) (2nd generation),OS=10.5 with: path: AppExample/Example scheme: Example diff --git a/AppExample/Example.xcodeproj/project.pbxproj b/AppExample/Example.xcodeproj/project.pbxproj index 7234d08..a93b920 100644 --- a/AppExample/Example.xcodeproj/project.pbxproj +++ b/AppExample/Example.xcodeproj/project.pbxproj @@ -437,12 +437,17 @@ "$(inherited)", "@executable_path/Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 14.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = app.oversize.Example; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,3"; + TVOS_DEPLOYMENT_TARGET = 17.0; }; name = Debug; }; @@ -468,12 +473,17 @@ "$(inherited)", "@executable_path/Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 14.0; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = app.oversize.Example; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,3"; + TVOS_DEPLOYMENT_TARGET = 17.0; }; name = Release; }; diff --git a/AppExample/Example.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate b/AppExample/Example.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate index 9f65d0bda56279110678250025141ae9410e8655..106aac6a059b1676eb79e10f8482900f5abe5d87 100644 GIT binary patch literal 222803 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 ZprS0c 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 z zPtWgFrYiRKUTx}9pN4c{0`~LXVaz&x9Fmg;_0wk{3m@R#()(6=dDEApB2}o4n@DfA z>096y(wk#?b4=fd&#;&DW}4nzr2mq6Y+^It@jc#b`aSH!9j2El{V`5(gFm^$UCcVY zTS)(u=a_f;fB2WTK`4XV8N7oGE%D6^?l8j<+)&0OP%AWB6zLoJfvS&QWRjwm*MtL*Jn^E3O0p41sxV%Fe z+(;(3kSU7Nm~|$z&Sch^%sP`%+v_EGxbEyOmb!#z(9te_e^qUk~`BlzF-ov zXIjfq9tNTJQ&5Cv3}XTI@&50~{r)Y?{(ZB5{~2$BQ05SEkUMii5@WWR(~}u}WX?ez z@>3A^p1C&Wn%Q?Uk7g`pnt3u)na)h?EVJ9pyczS&`~!R0kKCDm<|L;%gS}_*jVvEy zCRsXQ4p{~>hG{HE%`6+yUlx1HVozCqL7gmTInPD(o8=x4c#K=i@`6{q4nkRzQ-B(D z#*DMBVhi7+epWY;^#DI1b5`HV`a6H}7x#ID+F73mp=_~n3)xceF5Y0a3}nGPvzceM zTok1|?lzm9Wpn4*TJtIT&L&T`ZbZ|Yetdx$XPbgqWShY(<}jD}EMf^}pUteZT@6AX z$n!x?s-fNoe(!^CIfdK#;BU<11M|-w!YyP^NgCwOE`Rp-(L;7UWH+C}l;*Uf7h_N}hnhL`n`0j8 z=2*%K>@CMPY-cBjabG!p;WX#4w;Y$af}6;p=bXt&gO+XKwNmhJEF% zL>0_3r@P7NE#$0AeHzk)X0%`+vgUM0Iejyix0dTeYSI<^%q4fOO>E{n)<3 zPNIigXSl{qZgUrXY&Cx@iE=1FtehgwLddV{i zcamox^5u~$k9)}D9`eYP=TGi%kB7*RHzkpDL%qCeou6vXJNh-CVQCdVO<%7J%z~}CU2O$ zVe*E3joS-bhRybB~C5oTT>De@LbMH?wRYU*V?0 z?J3-z!k4fdcND&cA34Aw4s(>BImxe_#U8`$G5iu&_%{fBr1y_X)0#1;_0b6)1fjz2 zu5cbcqA10QqyjamjhPg#hx~=*FZ?O?R=6uY=tF<(uJB-FFT4{O3;)7tWGj50t6axB zE_@sJP$U%B zE5fWJa+8-Z3gIRq%r>Gtbuh;WbBt(8E9@o0Oe6Fk(U+0T;%nyP?L;hP1+qlA!-x&U zu!SQW=L9D)mk9HYFq??qxro_B{DIjQ3y~RlinU`r>J{^Q#hwJA;^tLc_TmwkNAZ%B z#yuA|m*VwlNE4dVk}jB6@!s@f5JMTkC}c0b4|^;A8*&x5v*PZdxc5}t9TdOMLmmgA z66vWyH`FVkMv1SO&0^NG7d8De|3f9tpx+Yeme6a7Yuw-#&-ptDMaCl$b`_ZnHxc>$bxqE_K;N68&!7EzCQiu_UTtz>-MTFJyDK@TPEs^t4*B|Ev$N6CCt zr6IDHl)dC9_*Th|$X>E5gBXg;CFLzCZ%KJee$6}wQW=rIR2JM>Dfd)rI7>Lly&zONIR&VNJ1gCX z{tRR=V=(X1@|Tvs^bFie>DesDTuZNEJ)8KJUvPh=-AQTLOUqvRzi&Oj{gpQNGO^J^ znUu&|M&2^=mNDxxACQyWL{Nby$X})vZD@yCmyx+lcX}dw8QIHB>=Rz|HVBoAMI6k%TpH4m0kbYAe>wTfCg3~e<{?|T#jLT%NSE(hRAa5mE zE6G}^8$B4x7r3cPOOe0QYSyxW7-X)rjUC8d$qp->MdnH}SCYBX738gSgInCe>?@gl zofXEET9sRqE0VGp}OiRm{AK9;&pX7yTK?5JobFaZF$( z_E5!LRFSWWnO6A&*{ZmUDza6Pt%~ng4fr3ac$fFc$Oq&^_NsZwPeXj8>T1lU>TXW) zEBdMW7jJ@4H8rcLSuF+XR#Uf{KC5LS3)!%hGF7sK)PA&wY>he_2N=4MG?)R#%=QuJ~f65D9@j3|Ah)WXO za1Hru$X~-;YUrVc9%|&lJZgA1H9n#!c37hUve)Q9C%Phcjo$QQ0ArcJEatI*#jIcz zYgmWuH4bBUHSDg2+p6&=^47S|Bjm0jcMZ8~{2PR7ns?3A$XhcV-bqb)Yi36OHSM&f zoz~2a9%@#mJ@V9a^EH1#y;^>+R&g5Bm!XVcGeyKwJ=d9uKI`bS&H@&*jFo(Y zJ=NLBw`}D&W?09YsN+r4Im>x2aG9%I<0f`l=S~p%_#JXk6}S1Z*?znQzxVOqL8z{t z>K3LXWhhTYYS9SusVje7`Rlf#HQq~IJ=E<(fBc=OJD54Fz>U>)|8-@r>sxiVVPAE3 za+IHuxvu%vy~_h0^Ng4L6NKu;$IR<_=k=12lGMms?>)k(NoU+lJ#(vfkkgz){d#6n z?>e_Ii+a9QPtWz^VW;&Ilav&sA`A9dKO8fuAAz0LFGX3*rhZ+_p}yYh>%G3->knZ# zqmZTkcqU@j^`~K<_3g91H&A~)=2G8I>)UC4v#D=3^>?wGy~thvO%Q6372j;ofk|w_ z{u?|DLJiHOVH(nrflTD20ELjhq5KVt6G=&`VP*~MP!G4+urYn{1{#iK0_ayHO2l@iDSDYCtdKY_x^ncpZcqtJT>3HvSa*XuOEktYrh6Fz?3u zIKUweBY$K08~@G~yraf9`HTBJ;z4V9^;-D779BCK7P7Zkhk3O4mMxfn z3v+4V7Fy_`g&ta*;3Sv1j+wQ%!vh}kj2A(urTi_6B4@WP z<|^v7RHIcw5|f&&6h_TfYPPC^x~WC(Pyi@>_@+?j&Ph`IL%qkV_&WG*h-JB{>x`?t^VOn5c^i*u+DoHr{HRl$dFow8+q=I_|uU8)>6n8#UVez#a}GZ<{-)+2+5R`fVFR z-L~=3XWRdgluTqHKjGL}+X$j4MOo~xt(~=PMIY>`?LdYwoKfhr?Rd_qmqvbVj&zd`6zc|I+NxqhnNr+)8Kcl@cFZI>9cXlEAf(vuNy zqg@z<_=utuCz2|-xpsA^M`N1Nl26b>yG5)chRw*@lr?|-9DG|v?NgC|0Q(+qMDV>n5Q+ImP zmjSr5PUCS0o#tRyotEPLbXtwu==3dH*~a%=4?>-NqjOP8QvtdF%lGT_;*B!{;)!w=u z{PMR&94o)z!3ds)=%u4eZJsM}rL?sn9@HSVE%d)z?xk<3Ef?(Wp@(R@iynwRqU|VJ?&vkF=Ue2C-p2RXQMCC*pXV}H zku&->e_^iC4{>Myd!s@(Fb@O&mha zUTXGIvzMB^)a<2ZFEx9q)2jrPsYXrguU9=9(gZu})d~Ig>P|Gh>4zEglA+gTPVzDc z^>!D%)$LuBNJ`;0dfP>B^XUCE7cht3_SO3ae{v@X`G0o^_4yxi_K~xXoPE5rKACaL zeX^r&pBl*4N2We@(#KBv*hwFG{C7fy`V3_RqZx~gecV|ev+A=L`|7h2^Xjt}^Xg+> zeeA8zFFXrEef81TZ2Ec=ebwo^lpnc*z5TzXyN=SbZo`FrKMx%e(%nddbeF);9TL*b zkODKq%peG;v|^!zV!Z|yN_Tf7ozmT1`*835t#y2Rt?zsJ-RE^)*Ta7sNBXUeyvc2z z1fi$|Bqk{-Fh`WmqtcR-Jmkk7ql!?BW^|$l?lh_&k(ejSJW=L}iX|TVjXKQZAQT`Her(ZOmepv640DGv)xk zALIKmz8|CCn6q3!&oS4y5rjtRbyRxvH>x(x(c7pIjAIJZnZYM4WEE@Kz$PvRq1Ys( zLGD<4iOq%G#L6Bkdu&-MP#O0d+mv>6;4Qk+odLMLShp7I+p%VjoyLdE;cLFd-eP}3 z7qLq)f9wiY2cbB##Q9#F@A>aWh2pAF6Z6H{SzI)3FYW^-{HA+wt@H4d0G8Py7~qH~s*}IL&o@EB+4md4z9{PJr)>_MOp9XiHzr?Y|ur8g1^; zpYa8=`HFA&o*(%I-yZF|qt~$!-yiM!qs=|q+@s|feTXAL=$%Z|!>zot1~ZS*`IsoY zJH~rs{>Ch0{Qn=L!!bMfhm+`S%oXnPfR{mNY*JE?o*d++Fr_I+bs}g;J0daP*kO#o zoMZhK$Bt$!<9VM+n0Ktc$Lf2mzQ>w*tc+vLJoZmy9V_eDWw@uYn~`(u!yxpoPT$Rk z`QB|tdj|0yGx?dT+zvwH?0j4*vQUtc$Ujd0aTTdT9n3M#9OLY2Tyt770B??ybDXZn z9Ys&$+}F5k=xUs<#y#d4FM`l`eT{#W3}nXNA>;E>fI<|dIPPJ*KF0sS0_=JGChTRr zy^P<@LF{(C+a7-k-yVMnb4?5glbY=0!gnV6&P3mt=sOcjV7`g=G_e-uoM_I8=A3BG ziMpFOoG)01$Fe%rvPzofybq zhT4uC`KHyV+!FQ+F!xXuu=zPjmZlL=q z_i%?(p5S*j)iykJ1q-xO_OVy z-AyZs-A${2jMJ)7lQ*b~ey0s#BHo(jcBaWXZ8!V)hr=A@J}-jMba|%BGhLn!XEF~N zKHQ5rKI(#fd^DXenZwt7%Mbj--z;V+%hAzCYgvzPe&lXu=ygVU^g5#hZ_$+=^rkPP zcprVwFvE<=m}ADD_{I$1n6ZqNm~DpHX6$4adpLoe%&?Ogb~3|GX4uILJNeiReVmA- zq#zY(Nk>I=_wjgEa3KhNqW@3y{mGm3Vh}?aP870!GLH9<)qnRU^ofo>`G_C!&L?L7 z#2tR}JP3UnkbuM_LxxWa2BFV&{`p_5L0_M5Vk>6*++3eu=1vfr>5gW)qnR1-zny9B znP#53pM$tZ|DBf5O!q!h-(O@W7w%`4Z_YC3tlZ?ocV`u*7$qr94Qk_#W<}6|#x$il z1DL>9*ug9rXUR6p_h$LtZ2ivG?`-|fHrwp8li&-j8_ z%)#$r;TG&`p?xjfkJ%QQZJ}>3Jc$k$Wu^eWxyUyc`Q{?uT;!XJ8etEMTF@G^E$YBq zxW`4ZEQ%qHcX*cxe1Q2EO~YL-`ULqF{mdckZ_&LVv^W9TsD-x|n`yD^i|u8x+>7O2 zEcfDr9KoF}zR4q=2caeQv&0)q5@9z>vXGrzLmh8Z9ZHZo&$hPDJS9r)1WLzraQW=-}Ei83Q zOEV(pQaP8(xm3=j`d{jfmdd-dEV^IXnMk6MW$BmvkKgzcS(Yxw-+4>d;)a)QW-E5P z^mY(h=DW*M(uOzbh8`DH&bpWj))LYA-`d6%u>4EkA~2YXrGf?f<|Iy3kbvoE)Y z<#U*#Vtc`8wxX0${fE8LrZ&pWijO|J0PijCOe zigUQJ6?eEFgjPn-oKEy$Fk_j7xmGUYJpT79@9}`gL1@(*xUW^RulkXd_|B^JY{H&a z?O-?i_=m&Du<90f@%>e9Y1M!4J>x|XS{)E35lKjfzc*Ibr5|>*`ggpy+MipKnF_S# zExKZkHN6-_6r+e|4C9!<3_izx*UaG?zQ-(Ubhc(QSCG%Yn;ly7G6<~=;m+5}v^E8H zvNk(~DTO_+wU4#-v9=~UT3ZkIzP2H6;~Q)BvsN!_k8_jT*zr2^uFHxy*LicDJ+Jfb zI`6KlNM))~gQj%Coa^GSvvqE1-BMPtnssbs3)|VnUd*-bI`**69@g3EI$f@N8idvt z#|-OzXT2HLn_;~f)|+8{8}z%rH+Hc;lELV9{d<^gz3$d;_l9`FV{Zxa|!ic$e{bbHha3&jxR7aDN-TvB4V~ys^<68xxS2WTYfDuj0*(-rVTT zje6Xu$Bla2Xts^I+^EZqX56UDjkWOi#zu2&oX2`D2BA&%yUFitQ*+F@X$qgB=S}W@ z(;R-_cNVaaB`jwp+t`i#oBrV_CpgW&ybMB{^HLJO<;}8fb~~G^Qxn~9u8Z5=+>O5Y z&21jUP@;)tG-J@)=3nrQ&3;Q;l8_!%)6x}-rVBNExqyX7VmBu!Z7S$OBDLw z@(JeJVy-Rb+OmqZY+y5Xy=4dIxx`g&;HJ0S;{oQ}njC#@O+z{|l7(y(q9|@}t37S4 zPaEE(Bb_np)(L#TWTx>M-(m+_e_}qXk!P#kx9WYX-nU-EeQ$k=UbeZLZN9&)9} zw?noay4fMy4!L&7wPO+Xxx@Z;9N-uyIm0=was#<{+~s}{+L;sI*f|uv?0launT=U? zE?^_x-097oe)~JUyVJWn&A9VCm$-sm>@wr7(v+hjRj5ua>R>m!8ql3y*wHRK+GR(( zWbkikhj#gUZLcUc4#>B+3q9$LTzmDrcNFiV&%Gb<3G(dK>)v^M#}E9--XOHkH}>VnZ+Ks2 z+~mGyyos6jnP;Cj_jz-lJ?-=EKJV`PjG5TkzB#zleLLC1ehzX3bM7BWU!w>z?Jq?c%2ScL=wW{&nqqeU7I$d>NMzj~%XDV*6=vRV z=Kagqj2qf7=YBc&ALcxlu*dy3c*3(FbU>~HaviW+{}y-XKrZqi-+_Y2bf6*nI?$X} zw8ae^u$u#RbHLpk(BXl;*v)}=nSd@2Ok^_pJfP15_H@9W4t#;^2kh&>*SMhr$Ai#6 zI{POt^@zm(_Mhb(<#7-?m=PHd`rjNZfDRAp?qDUVQiIymC4$z-dQjGbvL5V7ANu3{ zgYq4m&r(*gmi265J32hLo0I77;2qrW!AH2?Ltzq;l;r60kl)B5-#GLEWJUL=+~JWHxPc?x@y#Re z^CQ3T8-HNVBa6`Kk>#x75O#Rv1gDYj$OU9PavL2S`7f6aj_TlO0@9FZ*b25F&#}WC<0N)_Os->c9dnn*WI68p$9?~JR&tOVJ3U?y_j0@#B`J-)9@pP- zyFG5V$8~sIhsWE{j`nn-GkQH9j}DKo;ol&1A~D`O;m@5g&xvWcgA;$Vm}SU*Vk5iQ z%K;AI7ET=JGBKZFv)2o|NgNU7zg9+l;|Io}9!~ zKIC)0WDa(Javt08jZ^wLrI%A>s7HNTVBS+h@#ZOSo|=GnPkHy$bUxw}+|?;}bZQ;$ z`P2o>bLtv5v6EBxdB~F>bUGaw$wGE=kr%(`)5WPwHEQw(GM#oer|svo`A>I5w$t4( z^XainL!Q$gBhTrd(f#RVtY9_n=CpmCKF=lG&FQ;A=uCj$*_p&7BLniBDL^5LQW3e% z$aSU$vYhe#GroVu@9Ru|-1C_s=LmcG<=eWof?EdVHAapJhzHv@J z=k#)J3?K6;b20C^Re1B9H_z?EyXU-n?l>nogS$HCj?Sm16lE~a`ASs9PR`e+4iR*v z2fgV>B!h9!=SMM-DNJVu@|>TE+0V;${%g#9{tp(gkgXi#2(q0&#Z~O#{8OF>p$h@& z(ftM8UnodnPF6ifiTe%?D1-UNBbwRERZsfvu{Ewel#CCSE z7k&9R$3y?BqS##sYpXQGGJd9%hHM{-0Q`ac<+)w zcgZ}L>e3zea%m7cy(IgkI41A`lbFhfnB&q{nBkHcF8$2!==G9bFD=FlmmUV8%Lz$_ zY?o!bEZ60XWF{-Ryln56t5K6Ts7Di;Bll(9UT()2eB<(d?CY{FEZ+?_Tll6*FFmpdt2lr6Yqe&y|n)4BcFrjoGf)(G~MuG2fLntY;Hj*}-n? z%D*KZx^j^#T;~>ddB9`b(bc4+;1$x4pVzUMs}-n>Tff?jmbAvaR|hhRc+7rv9FuX^ zS7+g_ug>FFmSL|~WxXov)jjOv9}aO2d9Lc~>dPQ>EsWc_CfhaHuG!7CwCM0!CW=uK zIj@zW92JrET2-o33;VjJ+iULU+E~74GgpJqb?;sG=dPQ_zat*HuIuYMzOLizI=(LZ zb+>ct?uqm=m1lEa!vJ4Kv&*Kxy=NL$({T-H_`>9o*54`sngT zPX^$=ZwzHPv5ZFU8@jzQf#2|rn<0{;i=2|wOo15D(+f6&VX}+80yLp4#+~Xlnc#d7&vZGrW$V@hJl85}fhI_x| z-fvaH{I_b*mLBv*##@n?`IcF4jpse&yJZiz=JPuXScp5iC8K}4JakLOTl+c1HEwc; z`$6co{%Ml_`ted&*kxAl12es1gX_DFPj zTbH-vc?bD#&qc=DXM)h31nA&S6Z~)QxUD;G=+05}csIcR=5Av2c-Kwd%}Ne(kry{~ z*Bf`sBJW*!@5+0(4iPk@F?zf^1vh+GhP(6lmLK_rU(w@T`@Xv!yS;0-cMo%ne>u-3 zuAt9*_Il4Z?&;v3x$lkUBR<9~_kLmp-n{3{d)~U|t$Qai|Gjfu#C!M5d(Yk6d&bKk zJv@;z9}ayGD+103Qg zC-8fHa2DM@aGMWgeIV-tSs%*xP`-z`$wxtCdsv0))Z`81d)OO0ei+GMq8QKnOkyfu z@B{Ypa6b0^(0(4SVlC_0gDemA_V6kDjm{s-{v<6qDS%v0ilWOW<*0~GpH!m;eQ{q;mgBuA-gt733*5ww zK241`pL+AD-8?n#Q|~@C>(f${#&7be{XA_>8`{wUGd}G`PkJ)~J9_#Hzwsx3vzTS9 zWDWN7^f;&Z7kheo343~aod-eaS%`%A-8@UqE4ZU)uaXP5{!9nYWPK*vGufWCqAl*| z+1rd^9Pi=ApMAt!=J6f6e=^=J9+*V?&SH`tm8rudf~kn{@jaZ48rZa_=L~- zlG%KZj$i2bg&AI$;e{Dqtiav8*u`EBaD?NS<;9sG^ir=c^B~_#xn8=Pm+t1JOfTzF zpGGu6hL_R&%yzu@^1nCkVNWk#2H_wjxyVBa%21w)RHG)fsY5He(u+RyXD~w<&PXQk zHEY?xX11}DJ?!ToN4Ud%9`TeHK{ym50dj>hk(C_eCLaYUL^)&(RiQd<=|OM$G5}dZ zGx(I5%;H=A;4c=jluc}92fI1WDgNagw}WsvG0BiCoSIk3KxVR$6CH;0Q;Dj`71m!^ zf8n}B(11oXr8zCpVR#w~IDkG9crSrJm!KPCn8OeJ#C(2ZF>6@QMz*jWT_-q-84{Qw z!FjH5om<=q!U<(hSehEtL#~94X@)Knwx<)F>B>Zwqnm`@OX!V6iAX{k>?lzwyqU1=WOD0z``%UJa zl1=7I{)b&B`;)(M*U46~7P*scVhgu}aB|;BUI)8Mu8ZUY(MNK#B%i=cyqVma$>-zU z+FDdLLg_%;ADTSF*pb(T$$; zp+7RE7{c3_KZUzaAzO+MFmsCUkST>({hRIK6iYE@ioG1*Anqu|-N0Wr=sRU%WKEeC zxl+oNGC!|TmI}z3QqGhO(N9XZoU$cd7)}(Uu#1#q7{`0qMan5mX9l`U`7`=UslSwe z@E5YC)M3hH=rHAK>?q|)o(JJqWO_wEujt{GshIJVJ=_e!sdSu5x2bfSO1G(UP>_<8 z#tf;53Urea){dU?J`%)e7WFC0DBT?Bf&{xXd;F%kuzt zoyu=B)r-Ji=@iB{QpaImsdbV1d-Rc72dT}R+B~VfncADF&*9zF-c5ajTi99Z`$0HO zLd=+^I<=@n1a_0gTxrae#$0LIGMHhwl{C@BG8#KdV>f9&;|pf<72hCNnjf*JH0DlY zCu!tMvxbA5MYc3GQ7NlFR|P?~a7MDJ-1zq0^4NxOvQtin#xZr}*VImv1KeUtV)7tv)}dDH4Mtv=J<3Bs?Y zrUWf<$FI)Bd$0O){(bgvy4+Nw9t~(rQ`*s$9`vFw{V_+n7<8O&EM`bIkts~aJn8;s zFEXZ+Eu9|I$(2s7boQI>5l?x}%OIS-5FN0)^xjMFjr8B4m-PBbzk=O(Grc#{+fVun zcsKoZ%$nY;>F)*M4EB^E4H?KpR&tSt{1n8_GBm<083r?q5kwjM$nk1w7_pY z>zj1sE$l4oWajfbzMIuNSmXXYuIa?uQ%T@xJvdNLHGhOMyAYyUX+3Xsa_ zJG=0E%XX48oZ}*XW7+=8^@L|ZID0a3k_TO7cNf`<;HI;eq6~JBy%JT?SN7KEEW6IK zcR**^WzF85p7fy~1NeadAyfA2K{!WRDqzMOqxgbFtY#e>*~}h}a2zw_FhdR<=Qxj> z&tZlfX2|h82Z{e=bUE9*^qX0!u{mzMsMWGDOb*c#4(W%`Iyg;C+F9E%MbjB zo^$RG!nu4Sms`r^K6B|JS2OgHO9#2koXb49yqU|Jxu)UWT;9z!lP|HeTwn1U_LJ)- zX32G*M?B?45Y8RK-Q-R}Zt~%~xeHSa-}i6DhjUjZ0<-3BLUUSSH@VxR;nB zMN@jvn|?$xm|=_{npj3N7CXpe2YF_puRQw7^9{1*`5!+qA06iTgPmLp!g*!NTN<k&-pXs8~N=jzrSzu>mvUr=p(-l z@|!uodGdQRzc=&m$GiExoBsr-u(SN)O0)6Pu zK!)%(Be9nPG8CA`N61p(bKG$Odnusb0`^kicg$MgZx$n0fzzDj0+%sgfoHr7!UaRv zMM2#cEJ_L7a>265S+D_(X+}%B(4AiNWdyPnbTb9xnZ#GfQqYYQ{E=VyjX#mApj-u) zv66l0t>7V!U?&Cbq~IB3E@(Fe?WW)rt_9)Ol2HhmUK_*=mT(+*RVXVJsL31DqdqO@ zz+0H1kQoZ~q&GS)WQIa!C^VXJyvIZ)BYUCk9Oe}NB3B`~3hA=Y9q#jx$3eJoURtA@ z!rm+Fjly%WqryM2h^=_Dur~{zz>W%gx9~;GTG*_GZ}2<_7fDWP(vqGmWFsfJDM=$D z8O$(zyNH>Jn5l>iMchu2@ytPvBH!`@@)Vhm8H?CUkqvBS8#~#98!B=TS&Nvvh`Ebg zMZTixkfCTk3Q`z(in<;Deto!TE$Yyj0Ssa&!--=eQ<#oj7IiyCzrpPk{gH(%VL2<2 ztEe3m)m2ehipo+{mZJYbfi1I=u3Yh`4rzMp&$RIeYnJnAY3vn z_Ej=F<}FzjZw;sq<2gDos{fE7rNo^p_1M!>26D!qog@Xnxo`8HnN57?BXI< zxXvx^@_EphkVQ|e&iQ^ z<4;zx7G0OpL#YEC;wZ<_c`2Q|F4OA?NkVd7Aq{$ZJtKDVdUjr?Eaj<)TX?-1HK@fK z)T2HP>4U#RUjG?8eq9%(y;s_wE8U)GbXs~Y^Y{+G$I`#Egyoo_v>8g9q4Xy9bC_eC zOG!W5$E{+eG!`FPv53FD- zc2;gT`;e{NMXqoiyDTSP`DCOdHSW25F7i@<*CNEIqFb$~zlwHT z(T*$b;S|@n%L5*xze)*6j2F( zmqEC)TdC|;DksHzl{1r#9GJVZxhvaE{ZQP)vQ&EQD>z^J~0Y z)4Mf)Wv?lGTIQ%_j#{shfy`thCl#nnHEQC1Yt^GZEih-TF4#-0 zUi3w`wFWW@v(_5JIDEgBS!%6j9UD2tHEyEgS~{*}PqmZdK5C~S9l0n*NlH_W+SEms z+U}!vJ0cm(Fh-#B+B&a2nz4-MeeAyWSLmqrcl?0f8##b@O6Rb-h>D8+9XbhjpWnx9;b7 zv#vMmnzycZ>w35DLKfrZ>e^G??HuL=_Eh&@E^?V`+`z8tnX8`u>ouV{t!RsH*K;5B zy3ieasAmuL?4h0<_3WXZJ=B}Rr+m$~$W`wr=3@`_?4jN&*0KR});rG~?(>MJK{z4< zW{)U9A&OFln&=}!&k=f#XoEZvz39sTqLD8`zKAhQ^b}zS z5q1#q54wst%5hF|hI8mFLT3>=i_lqw9o2t@V(6>BTdn^YIa zF|s%4OgDPchyFwogZvHj+h9BsnZk5FLhc58k*$IL8eHNkGBvo59vkSfft@yxp`i{N zc0ex;z1Pqi4Zp*F8rn-kc^mG=n+?6$@GKYbZo})Cv!NX|ycdKUB_JhP$VqPU;Tw&L zP@Ixf$IUc~#~vDu<2}sM$SjS_(r5;sVjqqE#9WQ+qmg|yvX4fq*@B%kvXe%~kgt(_ zG&+ZUG_sFI4|t538@&j^jnk8d{1l`x6{v$9G`54rP3XZ8-ex3vZ>;mi)6h}lPxzc~ z`2)Y##*0|WCbqJJUC7p0PmS*)Ph)xf`~Km^`fm~@5lKlwDs9E<4=%tzWn*I029o$Vbx7b|X z<~i_Yb8q_h_ruM-+uXa&t5A)a)TRX;@VjUp$smT}8_lDMC7vnxeK%i^oiz9D<~uM` za~Ybuo#t+*x&1VkqxnOgAWw^c1lUarJ86-H?8xWe^bfZvfc> zMPCLWUkkU>Vj6Czh1+TIIbSg!{kK?v{#&eN7kfE?-dosb3-{dO3fFKyEoEw%mh@yI zEBb4hn|!#RmW3%sE!=lYJ84;;hS*8VX0)IcZIQdBURy@-8Ot~xgj?yNmG@ftbFKRE z0pIf*fATkrSj`r;V}@2{Xk~_02RX|nu5tsvg;ozRORJ|rxOGnKxwU+)UcGYGHYdC|Qw6T*mcGBiLe&21()W%G0%+&T(GLV^Un6GUf?53@qw3V%` zdudw(H{G@_a<*-RtZn6M`xag4!D!@ZD^FW_+J4MDe!~vh+CkgJ?BpmXIE~)h>b&hE zbkz1m5N;RZ6|&-H+T}*BcBLpoc`71PJ2~3P(N2zba{@X<|m|=_{nyJXv&TiU$ z!e@NJZ1mSo-ge*d13$76J-(TgA~a<U;w|c9yC0Q}o$IpIs6lLzfbCWh~z7;*Bmp<8HdR#V+!8`3G-y z@n#qEcDaUkyWGW`T^{iy2zO0JMzUc~U2{`_*C;|U?5b-UMiN6DX6pJb6R?-AlbOc< zkfp2rbhV$Z_S1C{OIXV;_HqFE{C5GuUG1o=9d)&%uJ+OO4)>9DCmt)2$EgxLXvXh)1?=dhYfqGns{a-Tr1VdhfQ9ZR}(Z`#6Q}yFEll-JS>G z?g9Gmo*12VPf2QCMYis;b=Ot*5|pA06Ztx@s_mQoSY<*^K+;tz>`sk~V9rSsRiA+J>J|FQhpR$0x+z-NiGvN;Vc4Go&>ARlOT;>{ndwp*s zd%py@^?u1niCgcNmYm4nuONjf!RzR^UwP#3r^kM>_4|OyOl1Z#_4}MJ_>qOIU^VO5 z$PRY1j{_X!Wf1P~8~t0-k-o&Di~i>CZ{Get;LZMjvI?{H_g?=k*i(OR_V;FgZ}vaS z(;z$`JGsb90Se(}2AFAp?+q~10DBo=F9Xaqz+MK}%K&>B;GPHcVK`CP%>a1@jKS;! zPb8aKn+6sYXp2 zBU7YIkzH^rk%Jk=2xN;KkIo}!^A+FlJwNgbzoECtzgdhOMCvP2w#fbbgBy=L%5hF| z20cce55fb({>42Hy2edzqtn6JX^L(JdvCBe2G8V6zU2?r zq{56tGLV_9_-zcShdze%$2>!Z@HQif zA&z&DV~G10;y#AV!*6rQ|M-aoxS1iVSjz@Bvz3FGeaJEFWXM$>@st-qcxZ^E$Tc(* zS`pKGGJrwY)krrtawOB4!Kch*7IXO;`x$93 zBjp?^=ScI9ly&45%sp}!vW`5(HRKy9-^lwxI4Vpcl9B>DiL#R@8KZJhj9S#eE~5PI zqngm1Ri;*p6922nn7@1;p z9rF>ojrogXZ;tZjs0Da; zly^tD)lsWhi<=#_k7L~BQ4o$zLtd&-om$kvK4N_@wlQt6gIGI=bxW~sDYg&x5o;f@ zqtI!r9I@^vb{6u)&f_=!M4niAV$B!pcN4pn?dU)D4ClDW73?ea0grjciy#~q!oA0( zBtIpoL_M0(5;^1Eq$54)jhm0_PbBsdH-(?r!FlXD&aKAjBJL@^6(5kE9Ox##0EH+* z1@siJr}#SPDZVK!u$y={8!tnAH+(lr8g3x|V?JXh-|!1d&`rF2@w>6F z_kq7YIb)IjL%IFchAq?x-=MfRg&2Srd& zK}iA#p(%F6iWL==qS$-GUQs~#&)nS-;6mi*17E+-^G9BZx!Y+w^Zu0i%(a^70{P*P&ahXl z@~O(;ya9pPfr9i{qSqOL5l7^O{o#PYZqckQ7#kxqUZw%lkm=6!U@l~OG8ZuyGrgGJ zOghtt$zU>>EGC=j%M546GUFIO6JVw=)0pW@DO1LTnF?k$Gl#j1na^CoT*+L+T+1wE z7BP#NCCshNI%Yjn!)#zSGMkvq%ogSW<`HHa^Ca^W^EC4uvzvK?d6RjEd6)T+`H1;~ z`I7mD`HeZq{K>Mcg_T)5tFj)}%Qj|PvgfgF*!FB9o5H5Dz1R#klkLamu!Gpa>}Ylj zJC+^Cj%O#a`Ro*S8XIOS*ct3hb{=~fJD)XJV3)ABvbVE$u&dZgwu-%*UB_-@H?dpU z``CxsN7%>NC)g+1XW8f2o$RaZ9`;T4UG_cpWA+pFTlPElC-zrv5I2+?#*O4gapSo0 z+$7G=1-L2PG;TUq%9U|pu7aD*&EYQN=5tqYS8~^I*K!NFMcmEY5^fo{oLj-IJ-|K4ZQ~y0p5UJ3p5dP5UgUOiySP`mJ=|VyKlc{*9``=?G4~1g z1@|TQ4fiegBli>c8+VX9%pE}tViAulNJ2KGAQicg8#P3YP&3pVbwg>WJL-WhL_N_( z=wj3h^+xF^3k_s`MuX9CGy+XP6Oj*1LX%NGnvRN4F)BeZpJ;%2xxZh>3k^KdJC0ZznSaW|ZX```?miL-DH9*A@C zP&@{Y#p7^3F2I-KdH6Cs9~&6(<@gGGC0>B9!q?%&_-4EW-+@=)mH2MF4zI^Gcr)IL zx8X9>0J;#2?|0@hA9G{2Bfne}TWmU*QAzJLWL{75|2h;6HhuxA0b8;Z?pp z-+}MQC-8}U5}(X>;yd$Q_!K^s@6Pw;v-!UK5I&b5$`9iw^Z9%MAK<6(h5S@L$X~*j z^C3RWSMYQBOZj>HW&Gv*b^P^wHNTo)!>{G<=GXD-`5Jx$zmea>-^)MDKf-V0pX8t7 zU*vc4FYzz)ukic$H~8=P@A)72ANim7pZQ<-U-{qogZ%IO5eu@27RjPpoEDd*iKVF} z)za0{&5~y6Zs}pU(9+X#k>z4bFH44{za`f))H230)-ukLZz-@`YME!b%rf6%Sio|* zrEmf8p%LdC1%QKc|Ezen=x4d9^(X!L>lI3N~E0)(S z`z>!-KCpaf`O@;0<$&dD%Qu!^EWcXqR)xE8Bdw#Xqpf4CW3A(?)x;11CTPv*dte08mTd%cV zXT9EfgY_osQtJxqO6vpG2dxiTAGSVX-DZ8%y50Ji^>OPH)*aTJ*4@@U*1gvEtshuF zw0>m$%=(q}N9#}4pRI?jM+BGP7CeGiXdpBc8VQYsCPGu8nQ)%aPDm1xg*2hN&_n1W zWC#<4iGoj08NLcUNS1cWI}mxxI=tJ z+$Fv$z9#M!_lqBjABlg6hs49;5%Ev)FY&0vNUX$3NU}-}Ns&~^BYCCfQVXf2be_~+ z>L6uF*-~GrpOho@mj*}!r9skQX^503jg=-#`BH&YBo#{~(kyAVG)I~%&6lo_mPkvb zTclg1Wzur#HmOpolGaJ1F8^X_xe>^qTa#v|HLE?UnXRA4s1`pG)6K z-%CG8ze|7EG@EX7+FUlb&13W08rT}z8rd4#n%mmg5^YJgWLpp0g|?oyi)`t(EZZR4 zVA~MeDBEaTne7r=xh-T1+bV1`Y%^`MY_n~1Y?s*<*sikOU|VRr#dfQ0ne8syD%-=h zM{L_{kJ`4|9WnQ+( zR#}im*)F?ex9pLd$W7(*vKa*~`Z_mgwv{_+5Mpgc$(EDw=$<)QL0d89l+4#-pF zLirN8Tn@=$d6s;se5JfVzDiys-zcw_Yvc{`MtPIGS>7VwBi}1;mG6@uk{_3!k)M@c zk$1_j${)xd${)!e%b&=f%Ad*K%HPSq$iK>e%758CcCWpGy`jC4y|KNCy{WyKy}7-G zy|ulAy_3DOy@&lmdry0&J%lkNHT0(-zd#a?KiZZEfo?6d82?3dfG zuwQAv!M@Obw|$*`y}ic1!M@SH$-ddX#eR?dUi$;~?e=Hv&)T1}@3OyYf6e~3{T=(e z_V?@`**~-YYX8lC(Ehvq5BnkeVFz+xhvcw1oDP>G(UIgxc64%dc64#1I8q&59o-yh zj-HMTN2a5{V}K*iG2Ai25pYa#6gs9lf{tm9>5h;i?3m-2>$t*krDKI-rQ=S=U5-_b zN=KEW+OgWP#JZWvgZ<>{4D;-c+sp4w4OP!rW8wTs$K?WOisN2_DhvFbQ=ygEUhsQT1Ns$ZR~PEm{15;d$=sPojz z)cLBRUZY;CR;pEMwYpkeqpnr&R@bTP)f#n!xbKCiy2zNUVuex)8z zzgE9dzg53ezgK@ye^h@`e^dX|kcKr`vuh5`qj|L?Em`ZNb=JCQDO#%5RqLjuY2CGp zv`nqPHbBeMhHE3V3ED)hK%1%swM(>eEu_uX=4jVx*K0Ru3$;bsjoMAxa_u(lcCAXQ z)>doVv`4k=+GE<|+7sH7+Ed!o+79h`ZI||{_NKO9drNy;`&j!#`&2um9oCL$e`5I2kXQ2 z5&9T?tUg|!p!@ZpUaXhsbM(3TrTRSmGJU>o=vV63>DTKw=(p<2^yT_(`tAB1`d#`O zeXU-jZ_)45AJ$*iU(t8zuj;Squj{+@J^EgKzy7ZNss5S%x&DRzrT&%vt^T9_tNxo4 zJ9($YX>|%t(J47?PQ~eRx}8m(&794hEu5{LZJmkEBxkZS#o5Dov9q5u$JyUGz&X@8 z!a3SG(K*>U#aZqQIm6Bh=M3j;=cUg1&dZ&*JMVC=aISRT>AcIi%30~Ga#lN6JJ&eZ zI`4L_bFO#RI5#*Saz5;Q#JSD+sB^pXG3VpXXPmp7uR33IzV6)Z+~a)D`M&cb=a0^x zoIg8%asJ92a{lK0!+FU0r%Q9`E~m@oa=Sb(ud9Kpp{tQA+11I_+116B;!1UOb#-&4 zxw^XsxCXigxdyw2xN==XUBg@xT|U<&m)|wnmG26=rnyR7rLM56!gYn~O4kC{Rj#XD z*SHqBZgeeiEp^@Qy3@7MwaK;FwZ(Oh>t5GZ*L|)hTu-{5ay{+Z;d;@v)Af?;W!G-k z9@m?${jT?2AGkhoed_wf^{eYQ*Fo3su0LFd+!nXhEx1Lu1< zyTU!gJyH~r{xYxQjy0^PuaKGq&)xFRC zhWl;z`|c0iAG$wvf9C$m{jK{)_fPJF?!)dQ?msNuHpm%rnz7*K?`I@PKE5=UUG~ z&mzx_o|`=DJnKC*o(-Ojo=u+3o-LkxJokFGdLHyV=6TlhoacGZ>z>`7J)XUu{hoI{ zpL#y?eCzqnbI|jbm-AY@R_p|t9YGWueXKw0&fRzk~i7g$(!oU@Me0myxHEq z-hSR3Z-4J#Z=QF!cZ7F>ccOQ)cZzqKce=OSJHtE2JJ)-u*YMupUFcopz0rGmsAuL?P2VUgHafjaWbA!gYy!n2WE%HlK;nMqa$1A z7x_b>Dn?^;gELSS<6_*zx92}K4*679PG;7q((>t{GJk#`voyb=I8YMysjXAHbGcyoN2+d zWX@w+F|C>NnKsM?Ok0CDEQZw(4AGDbn;{!^!(k|fYG{VOnQ6~-U^+4hOd^xSBr~1J z|GO|LOe*=do8dIt8y$gPY5WBID&Q-Ducm)K2>c7ce?l%EHG25e2EzjRq}^Es!EkB0 zc^4yw4Gj6zrs?@%GDXiVFQs$yyg)dofTRpg2?ol^?A)g|$_z~LR}{taMrP-s?9y_Y zd3-c$UjEcTae(y6u!@q*Kqwq6@rTLmKQgTklQJvH10#c>;N)OYFiZ+m%=$+KOA1P7 zk|s2Y{*_){?k_1MMU{jz1CuKXb4sR^`c#dSno(L34$KNiZ-QiKKCCnp2#5VAR(O0R zu4vOvOyE!}MncFaw!E%wT2+ zlgkWch8ZryYcw<(8%>SoMoXiWalUbZ(QXejf)G2B8O4ld#!zM_lctR$|1S>|k9N*xANaGs#)V}|`ak>8d>Hfk%VrXV?O8EG~gOS1;`P9y{5+cn_C@L)^ z9gv)rnvvZnqgz7v^e$ZzQo46bPe{w`o|=%EkEC=3KEib{hsX8Nb)7fqc!y|6ft?++9g_)E&>B;}P> zl;;OxcN0n?l9E5Yv?3fz8d4T0Nzcup198fG4Mp16jQC)6wXwEs|8Jw5G>kNWu#sLA zC=Z9?dw5o)))qc>&Ka#WFTXqxC<#&Qh>{^nqVR;jbIE9r3&jZdBXpKi-3I_HK+gWCGk;A_|k*lG#_yi$KS0$x|28u;hnon#Y} zh6O?q9Ue*|tu3e^%NL0uI*`+Y#4bfW%SV~VXq&bhnd#2+awA;!C!*}*)^ zOd3Bpul75$1+joz!7SD0PQtITUgAEUo9$QW^AZ|#fp z)to?w*j+scZLyv~FqL5>h)6JDQx8*0ozo*W-Kr?MOMj;>te zq^6{%B&4LJbxug@)17?m+C81LD?P1yO0wAzA2XlQq4>nesAN7fGU-q>G#xmT*MX(^ z5eGFC^~}Cv@+z4FMwZcTA5j(GGT$-ZGe0mt65s1*<`?GIG2vh_acYU9rdR%4yC z0Nof|$-0aor&B-!GKOqJBe#w*WSg@sq60G27#24mr^o2;Y%4M#huPM2K*+M?vCgHA zppi#i8m`1qTRqB?}lqy3-D z4rPZKK4X$W23KN7up4a~|Io-<^yZ$K6q zjTUhUM&{(@^ck2njHHSti7z8-bZ$D~&@96}cW!dW7RmEEwwT)~xpQjA7Tr?1&zl#~ zZ|nrtSIJH^3XCby&wh6DDkBhOvw#guJjQ0kXR2lksMi#|T*yu(<|bx|h}T}t7P3KR z5}5#!4<>`t*;3jEMQkx!VoWuH#{H>Mk(fB ztSFA9jHSAtrdrNENE&pR5g0)yVX-UQ=#@v=?S^3hxf1C#pQ^`vpxPKwEcsJ3`D}Iv z>Gms(Kpts)w2jZxHqIvB65#0lzZ6Y3Co(*-?_Q&69wimUKJTTUSCV^;ecm6<^ESzI ztq~Y=Y~C9!@%?B+KP36DHv*&0`!nhMl>M>}2|d7mO(b-ov53+cCp=xdbTKLTo(j(o z#*OA!{u~)gv+&=zmQ30fwLN=~{hj@TJ;WYnkFbBTf3Zh7hGRL7LmcLK&cazaffG52 zvvD$K=Nz2Eshq~?oRf2LZqCDbxdvQAt`XOmYr-|pW4*D#*ko)m?ltZ+9xxs<9x)y@9y6XWo-%eA&l=AgFB&fyuNbcyuN!-e zea4%{TgE%ad&URGN5&_lsoZ&7E3P$nKG%l3fNRUO(2GyF64T07jYMJy|~_7I@gEG;4--^E}QGi_2Y85{@eiLGhi8Dy}%{_ z+aK7ez+MLIT3{asb~mt}1A7QK4Y)SI^#N`IaF+nL9Jr0Zy$swJ!2JcNHJ~&=d4Q$@ zx)jjOfHnbo8PJD-eg)hZ@P&Yf0xkf29pF0wKLYqwz@Gp_@ZbYQ9OMU8~x*B_o^J7svv-xJcr`9B%Dul$1jZ|@~PhDD9 z6=s38RYm4pXEMwc>yNxZ`HWzGfJ~xJ5!mB=k(Mt1uZd!C(Ji$ z<5D{w=1`j>Wqz(5`sgH`1QcUEU3(>`sHh?oE|1K0;v!gFGyr<%8J#PeF}@QbH1SnO zhzXh^flr|zt)LbGpcd;Qc>kUz~oWm?75$;H8< z$@$asC(kaOI@@0mE-mn1GNqniZ)|L+7gAb6)*C{xw6(*QJGC@idffHM=e((4Z=59U2XhuJ)-f|F6EkqF_Owyv`UW7mc^B^{H3?Pw()bh3m8Z`NVCUoir>fJ#$c2 zVsXK7(;Y4vfL-TP$JW)jTC7YFHGwlf*Tr*;Z{kSB4|g=aT61P+IZ^qENpO6fizDiJ z<9~K7g1a?R>*oJ-B>DKky(7|udwlAxbq%gLl(mC=YTfbA$TJ~1UN@Y|hOUaVb*oRE zT31_Z+h~?)w%+_qK_tYTtXof0t*?pHe!ow>sjk}1x@uc-_Ij$k9;d4&(#i+_*Xhda zV4$d=))*Z77%!?@B6s+(PwijVIMnvPIqK%fn4cp{D)o43_eaX#=2LgoRlZqTZ9S(R z=l_^B9TX@C`g4Q%)1&q!>7>u`efUV^9=HFuEP`^6N80oFzqec+^I%5goZ5rm5ozO- zK6OG}T-5Sla%PfZem;fvsm~I=5UKL%f2{Coo#j)z(Po->NM4E5PL^wKuIq-)+pE3t zQwzcwGYxh6C%Yrdx9UH*w_6KbPaNwt60?ZdqpX~qlx9>agX z<$`-R(#D-Wb=p7gs*_QQIPbI%BY%YY`iscUi`jMe(MOT`U-qfD)K$MZFttN=wvaNR zug4609%pIT5?Q)`=OQe-yX{9Ieb$sJaEB`3eMBwp^mj@10xf5YYr?uSTQcKg(s z|Ew44lP%(k{XcD$;eL%YX0K1p{%4J;PrDzAl>LTJy`iqM&B3i5_OnH128rI+Jq@&(x~@+D%rpKPxnRE*;B{V_mDEW9V1ky_D0S~^&k4wS^up1TE%yABWkZ? z%_19C>C?5LV_Q>litE}ci5f&&^RZ98zOL4o^w-M8nU+{HW^$^KFKQZT;HN%y$-mP; zQ}71|!ZXS4rjtF}$PzDVfjTg0HK-*z54A$A(fOzix&XCB?NEE;bK?u+OXDl!fbq5Q zjq$DVo$-AQ>WC5||B?~es7?M#A)B;+Fn*5w`^7kH{6zjb65W;EC_2h?CsuU-R$?f! z*O&~hPi+!^kwgOr1xtd(ezFy%Wu2F4Q5mJgS0_M_ZPIn7$tjsZcVia?$VTe;Qi}Yu zNhGKiGN0NizLb2jAFL>{6+E$Y$`rD_tFDql$EBh>pH6j4=@sFrrRAhC@pnx3+-8>+ z(KS-COFXU}Gt2#DWO+BXWQqEaO&}=4_|a$=Ss6sxOx|iHG5U{md-PvBl@VggcW4M2 z%6KYKuJLOn8fN@PxBHXb?nPmLbTkH@*cE23k!TF#sY0XBXyc&qdlf68abzv=5981{ zdY6%{A%W0Db7N3+%Z|oPkF2OO&mw;n-Nn_4iT!7mT7U{^sR1;__|y37xKc+Og$7pkecD4Sc2KY{hsliSSk2zrKMxeYyvwxh?;2W7~Kh^*3AfR--(s z4b6K0Ku4lP9;QTgtS5gg2j;My5Q!1Sn8y}u#R3+wgl$*`HWAn)V3UFE1Z-zuy8xR4 zY$~u_f$dg<9Z@2&9#xdsLy1f?iR^JqQT96rmqNdfVw$y05ilZ^c7cmTLNzKHQu;~w}z z+!NS~f$ars?`nK8?uB~;n+|LSu$i>FHgPUX*-7=s_Ep7}gOBqBYZDGHot+sB(a-cT zIO=%?%E`9ExS~U3^>nhoJaJ~QAUt(9&Sn(c7xyFk_Yx~Af(4UjhXbJ@s+yXUuB9LC zmvhVh9`1ejw;_9TqWjKqe>{NfNF6aEC$kFoCmR6qAX32K_yU&emOTf0=3I9R+Tril zrFuLmpjGdJRS^j_g>4uf5fN`ZoQiig5l=jdig({Q@m8NO^Nh#7h)Cm!RHSq2$z$dS z;4&)GQ*a@kii3C>o{o!fF)qQSzzzVG)Hev&!N3jyHW%2Tzzzd857^-~_>!1NSHwhm zHWld+rbv%DCel;RiS$_z>8q(oUjyt&Q>3paB8_jr3+WHAqktV9{Y`uyx9Tv5dnsN< zMf(qN05lUWJK!H38U(!1}6jHC|0cdlInz{{qq8 zKqPZxykvg&W<}FG_h-znp4-R`TQgl$wDA^__MZ5(FY;S9X7wKU%AL6zMs1rle=|vI z_Va!CLE6vvBQg;A#=$E55Plfg0$>Ai(yKKiPl}Rlo%pfiH}K;p@s6k{KTSosunIqn zA0pXFA#o*`mA;7gQd!=KU&1frSMV@kU~i62 ztyllwW3nxIm?0WHA^Xi|#GcPgub4%i{U?vGMXy8xNB<2GBfcxamnXw>eGFf|2f-ID z!wcz8WC~6!k%QQyV-F|s>3jykmpt>yF0AA;fn9WZ`11Yu0fa<8hvIu9#djdZ_olk= z<^F2byX^@xa6XS8%cQO4hw~%&k^CrrG*5h#CBQBP_7-4?JzNIt^0oXpg4+asBJbmg zp}LJul5Yo=#0si_t)?5@^+<#_HZY;Yv8AQOB2(Y%xM(}-+2@nb`+dYu@9;HUA$wEw2_ z#0cC0?20PBgePWTC6EUu4vh@^%L@bH@dZH=bPSSLAoxqdBZ}x2?BPY^d3{s1XYjM= z*v$lXRV6` z_tfyqW6ER&zmmU`jO{9_O71mP$pgS{1M=Ji8RqT(_Y_HdWcoiHPv$pM?LbCitEnBf z679g>hZpkqk@u^x_eK0v^80>b-nyzDlaNRG$0%jnfqk%&Cr>~;bebCCY5rMC_ztQe z9;O=NIjSKZsY^rP-&*xRAMhXY9|8LWuulT}6tGVNOM-UK0Q)Sk&jI^9urJi`pTx-gBI$2z#OXSDp(DnH1zRkHM+*<^%as-@u&7j~IZ}_?{w;V?@yl4OZQl0K$9 zMIuR`#6#HJ3?*5{TcV*POC*%^Sv{Fd2m=-xO0rC`6k4WQf|hBP>6Ri(v8BX9T#PS( z{SsIb+&%#8*T8-Q?6<&v2kiI2{!n9yg_0~4F$g1}q#sQPe>Nff{Tzg60YVx{vXF@v znP5iZ5EdFqieK_INBL&UQVQV`V1KE!5Xbq~(}eIg%L<~@EVon3{2Q^%mX*{pAFRtV z_kP%{tlF|RstMOnP51|ea3xir2jj>!b8NIcL?PT{*=*TjxyN#^Wvk^r%l(!IEX3J3 z4D1nLNkM-BdlWbZI2Je#I0PK7u{<2pgxf8TSsq6TmM4iOT^OBC&y8x>AhR^ZW416ZDzgSS|ST?0n7J7jSOiJivK@YXDqB;2HtfxW>vwskB<6QFg0Dscd3W z+1!k>bFI%odFG+C(pREb$yhXvL1}G5p?uuhjQ$XH09@=h!BUM4wzajj4Z+fSK5#86 ztrq~-^7OE@cCaQ!u(T#nEYBlYS(7Q2t>Ur77nqf$TGJvL(%Ox(cz!*Z%p4b6a|nyp zUe?~$bZZ}LhBecgWzDwswe|y!w6-m9?SN|!TnFGf0+#?Bk-jA0l54E}V=NAinrZ7W z%3>#z#gv$t=6at)@hqS?iK6HSuCs|^0YT9kzzgXQa9!v`I`W&KXf?;W$XZJ1uohcO zfJ+6gYn8RkO5PhlhONinKzSO=yk;dcth1xs&Z69=Q3Odu8MyB8-139WOosJJvPNVD z>*dxffV&X5p1@sHZCzl!imVZF7X#Pp-(MrLE@TwzqWE>6-L{7(uJa68wD>W(+x<`6 z_Ay-}vMwfRZ;ns+%35t*ZCztsYrWgL4!8{9GJ(qiE*rSMz!7220j@uA1ArS?W37pa?&g>o z*-AxskSV%Dj+v2h=VbRR$nKL=cAo-nuqnIG)aPPbU$X9^Qv0&?72tA#8(L+3)%qH6 z!+;x2rS^>Mzp(DJzC{J_4eOiM{lMh`HypST)z-JI?@$382^{g$|Ly%3){lu$eG)HJ zeF9e;9Pwcv`N7+UY`vtz*xw=o_&G`YMSR-1FWvBQ@VVjyz5P4_LpA zDz0y+;u=E*@O!Gb#>Ocw^)6Ecf3Y5n3hi%HXvf!+$IS7kAW)(G%X(B`1Xkb#Bw&FT zEP@rdiNN`Qn*KVQ7rR5vY?eimu2CV=0UCOcv)Ghk?63vLH)d zHxPMSdi+lF|GoS2|5q)@3PDQlG~g~X$t|vz+^{f{z$8=%WaJItph}n}kg>lUxCMX1 z@M)MLlfTOZpq0!=qky}DM1O?KN%V)ivaaY4_nVpN8sP?FqJ(RO>xAopy9&6gfxD(! zSST!_ChA(?uKV{*lyD292)D+YoszlpJ}B7M@9?tQ{L_~`)}%c(QNnE`?d|bt_gsT~ zxf2I}xAEz5T@K$UlhrbFACa(9SWVWfg*%12gjGVNP$g6YcLQ+5;a>#YjlkUm+~UZZ zwQx7@6V~&wHEWLSimw8WEN!2iHS79Ur2l?J`_yaJ=GfmS&<#}lbb+kU-T~Z_6PBt^ zSa3FTY!@D<8u&5bZmDx&+Dx}YcrL0upQXxk8C9N_Q;mCNoW?bCyezy)EV%HBuuFJV zcuja+*e&c4_6qxiH-NhhxZ8mvEnETIO5pAU?k?a~0apoJRgJJerZ?Y>S?~|3)~q(Q z<{Hz2*Zkj8ng9OMv+y0&gWm(U+SG$T)vE{p5Drs*4gt5eQaA$K-G8I~Vswa%h$v5^ zM2=eUb%ZC8r#!8X<4MEUn3*Ke9)VDlDTEv9$z!zPQ{ zs0Du_YQcB@-^1~Ll?4~m2)SZ+;2w#QEB369Troq;BIJr>`u}L9NT&bWPm|pKB3VzQ z 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 some View { - VStack(spacing: .small) { - TextField("Event name", text: $viewModel.title) - .title(.bold) - .focused($focusedField, equals: .title) - .onSurfaceHighEmphasisForegroundColor() - .padding(.bottom, .xxxSmall) - .padding(.horizontal, .small) + @ViewBuilder + private func content() -> some View { + VStack(spacing: .small) { + TextField("Event name", text: $viewModel.title) + .title(.bold) + .focused($focusedField, equals: .title) + .onSurfaceHighEmphasisForegroundColor() + .padding(.bottom, .xxxSmall) + .padding(.horizontal, .small) - textEditor + textEditor - calendarButtons + calendarButtons - allDayEvent + allDayEvent - locationView + locationView - alarmView + alarmView - membersView + membersView - repitView + repitView + } + .padding(.horizontal, .small) + .padding(.vertical, .medium) } - .padding(.horizontal, .small) - .padding(.vertical, .medium) - } - var allDayEvent: some View { - Surface { - viewModel.isAllDay.toggle() - } label: { - HStack { - Text("All-day event") - .headline(.semibold) - .foregroundColor(.onSurfaceHighEmphasis) - .padding(.leading, .xxxSmall) + var allDayEvent: some View { + Surface { + viewModel.isAllDay.toggle() + } label: { + HStack { + Text("All-day event") + .headline(.semibold) + .foregroundColor(.onSurfaceHighEmphasis) + .padding(.leading, .xxxSmall) - Spacer() + Spacer() - Toggle(isOn: $viewModel.isAllDay) {} - .labelsHidden() + Toggle(isOn: $viewModel.isAllDay) {} + .labelsHidden() + } } + .surfaceBorderColor(Color.surfaceSecondary) + .surfaceBorderWidth(1) + .surfaceContentMargins(.init(horizontal: .xSmall, vertical: .xSmall)) + .controlRadius(.large) } - .surfaceBorderColor(Color.surfaceSecondary) - .surfaceBorderWidth(1) - .surfaceContentMargins(.init(horizontal: .xSmall, vertical: .xSmall)) - .controlRadius(.large) - } - var textEditor: some View { - VStack(spacing: 2) { - TextEditor(text: $viewModel.note) - .onSurfaceHighEmphasisForegroundColor() - .padding(.horizontal, .xSmall) - .padding(.vertical, .xxSmall) - .focused($focusedField, equals: .note) - .body(.medium) - .scrollContentBackground(.hidden) - .background { - #if os(iOS) - RoundedRectangleCorner(radius: 4, corners: [.bottomLeft, .bottomRight]) - .fillSurfaceSecondary() - .overlay(alignment: .topLeading) { - if viewModel.note.isEmpty { - Text("Note") - .body(.medium) - .onSurfaceDisabledForegroundColor() - .padding(.small) + var textEditor: some View { + VStack(spacing: 2) { + TextEditor(text: $viewModel.note) + .onSurfaceHighEmphasisForegroundColor() + .padding(.horizontal, .xSmall) + .padding(.vertical, .xxSmall) + .focused($focusedField, equals: .note) + .body(.medium) + .scrollContentBackground(.hidden) + .background { + #if os(iOS) + RoundedRectangleCorner(radius: 4, corners: [.bottomLeft, .bottomRight]) + .fillSurfaceSecondary() + .overlay(alignment: .topLeading) { + if viewModel.note.isEmpty { + Text("Note") + .body(.medium) + .onSurfaceDisabledForegroundColor() + .padding(.small) + } } - } - #else - RoundedRectangle(cornerRadius: .small) - .fillSurfaceSecondary() - .overlay(alignment: .topLeading) { - if viewModel.note.isEmpty { - Text("Note") - .body(.medium) - .onSurfaceDisabledForegroundColor() - .padding(.small) + #else + RoundedRectangle(cornerRadius: .small) + .fillSurfaceSecondary() + .overlay(alignment: .topLeading) { + if viewModel.note.isEmpty { + Text("Note") + .body(.medium) + .onSurfaceDisabledForegroundColor() + .padding(.small) + } } - } - #endif - } - .frame(minHeight: 76) - - TextField("URL", text: $viewModel.url) - .focused($focusedField, equals: .url) - .onSurfaceHighEmphasisForegroundColor() - .body(.medium) - .padding(.horizontal, .small) - .padding(.vertical, 18) - .background { - #if os(iOS) - RoundedRectangleCorner(radius: 4, corners: [.topLeft, .topRight]) - .fillSurfaceSecondary() - #else - RoundedRectangle(cornerRadius: .small) - .fillSurfaceSecondary() - #endif - } + #endif + } + .frame(minHeight: 76) + + TextField("URL", text: $viewModel.url) + .focused($focusedField, equals: .url) + .onSurfaceHighEmphasisForegroundColor() + .body(.medium) + .padding(.horizontal, .small) + .padding(.vertical, 18) + .background { + #if os(iOS) + RoundedRectangleCorner(radius: 4, corners: [.topLeft, .topRight]) + .fillSurfaceSecondary() + #else + RoundedRectangle(cornerRadius: .small) + .fillSurfaceSecondary() + #endif + } + } + .clipShape(RoundedRectangle(cornerRadius: .large, style: .continuous)) } - .clipShape(RoundedRectangle(cornerRadius: .large, style: .continuous)) - } - var repitView: some View { - Group { - if viewModel.repitRule != .never { - Surface { - Row(viewModel.repitRule.title, subtitle: repeatSubtitleText) { - viewModel.present(.repeat) - } leading: { - IconDeprecated(.refresh) - .iconColor(.onSurfaceHighEmphasis) - } - .rowClearButton(style: .onSurface) { - viewModel.repitRule = .never - viewModel.repitEndRule = .never + var repitView: some View { + Group { + if viewModel.repitRule != .never { + Surface { + Row(viewModel.repitRule.title, subtitle: repeatSubtitleText) { + viewModel.present(.repeat) + } leading: { + IconDeprecated(.refresh) + .iconColor(.onSurfaceHighEmphasis) + } + .rowClearButton(style: .onSurface) { + viewModel.repitRule = .never + viewModel.repitEndRule = .never + } + .surfaceContentMargins(.init(horizontal: .small, vertical: .medium)) } - .surfaceContentMargins(.init(horizontal: .small, vertical: .medium)) + .surfaceBorderColor(Color.surfaceSecondary) + .surfaceBorderWidth(1) + .surfaceContentMargins(.zero) + .controlRadius(.large) } - .surfaceBorderColor(Color.surfaceSecondary) - .surfaceBorderWidth(1) - .surfaceContentMargins(.zero) - .controlRadius(.large) } } - } - var membersView: some View { - Group { - if !viewModel.members.isEmpty { - Surface { - VStack(spacing: .zero) { - ForEach(viewModel.members, id: \.self) { email in - Row(email) { - viewModel.present(.invites) - } leading: { - IconDeprecated(.user) - .iconColor(.onSurfaceHighEmphasis) - } - .rowClearButton(style: .onSurface) { - viewModel.members.remove(email) + var membersView: some View { + Group { + if !viewModel.members.isEmpty { + Surface { + VStack(spacing: .zero) { + ForEach(viewModel.members, id: \.self) { email in + Row(email) { + viewModel.present(.invites) + } leading: { + IconDeprecated(.user) + .iconColor(.onSurfaceHighEmphasis) + } + .rowClearButton(style: .onSurface) { + viewModel.members.remove(email) + } + .rowContentMargins(.small) + .overlay(alignment: .bottomLeading) { + Rectangle() + .fillSurfaceSecondary() + .padding(.leading, 56) + .frame(height: 1) + } } - .rowContentMargins(.small) - .overlay(alignment: .bottomLeading) { - Rectangle() - .fillSurfaceSecondary() - .padding(.leading, 56) - .frame(height: 1) + } + } + .surfaceBorderColor(Color.surfaceSecondary) + .surfaceBorderWidth(1) + .surfaceContentMargins(.zero) + .controlRadius(.large) + } + } + } + + @ViewBuilder + var alarmView: some View { + Group { + if !viewModel.alarms.isEmpty { + Surface { + VStack(spacing: .zero) { + ForEach(viewModel.alarms) { alarm in + Row(alarm.title) { + viewModel.present(.alarm) + } leading: { + IconDeprecated(.bell) + .iconColor(.onSurfaceHighEmphasis) + } + .rowClearButton(style: .onSurface) { + viewModel.alarms.remove(alarm) + } + .surfaceContentMargins(.init(horizontal: .small, vertical: .medium)) + .overlay(alignment: .bottomLeading) { + Rectangle() + .fillSurfaceSecondary() + .padding(.leading, 56) + .frame(height: 1) + } } } } + .surfaceBorderColor(Color.surfaceSecondary) + .surfaceBorderWidth(1) + .surfaceContentMargins(.zero) + .controlRadius(.large) } - .surfaceBorderColor(Color.surfaceSecondary) - .surfaceBorderWidth(1) - .surfaceContentMargins(.zero) - .controlRadius(.large) } } - } - @ViewBuilder - var alarmView: some View { - Group { - if !viewModel.alarms.isEmpty { + @ViewBuilder + var locationView: some View { + if viewModel.locationName != nil || viewModel.location != nil { Surface { VStack(spacing: .zero) { - ForEach(viewModel.alarms) { alarm in - Row(alarm.title) { - viewModel.present(.alarm) - } leading: { - IconDeprecated(.bell) - .iconColor(.onSurfaceHighEmphasis) + if let locationName = viewModel.locationName { + VStack(spacing: .xxSmall) { + Row(locationName) { + viewModel.present(.location) + } leading: { + IconDeprecated(.mapPin) + .iconColor(.onSurfaceHighEmphasis) + } + .rowClearButton(style: .onSurface) { + viewModel.locationName = nil + viewModel.location = nil + } + .rowContentMargins(.init(horizontal: .small, vertical: .xSmall)) } - .rowClearButton(style: .onSurface) { - viewModel.alarms.remove(alarm) + } + + if let location = viewModel.location { + let region = MKCoordinateRegion(center: location, latitudinalMeters: 10000, longitudinalMeters: 10000) + let annotations = [MapPreviewPoint(name: "\(viewModel.locationName ?? "")", coordinate: location)] + Map(coordinateRegion: .constant(region), annotationItems: annotations) { + MapMarker(coordinate: $0.coordinate) } - .surfaceContentMargins(.init(horizontal: .small, vertical: .medium)) - .overlay(alignment: .bottomLeading) { - Rectangle() - .fillSurfaceSecondary() - .padding(.leading, 56) - .frame(height: 1) + .frame(height: 130) + .cornerRadius(.small) + .padding(.horizontal, .xxSmall) + .padding(.bottom, .xxSmall) + .onTapGesture { + focusedField = nil + viewModel.present(.location) } } } @@ -283,221 +332,172 @@ public struct CreateEventView: View { .controlRadius(.large) } } - } - - @ViewBuilder - var locationView: some View { - if viewModel.locationName != nil || viewModel.location != nil { - Surface { - VStack(spacing: .zero) { - if let locationName = viewModel.locationName { - VStack(spacing: .xxSmall) { - Row(locationName) { - viewModel.present(.location) - } leading: { - IconDeprecated(.mapPin) - .iconColor(.onSurfaceHighEmphasis) - } - .rowClearButton(style: .onSurface) { - viewModel.locationName = nil - viewModel.location = nil - } - .rowContentMargins(.init(horizontal: .small, vertical: .xSmall)) - } - } - if let location = viewModel.location { - let region = MKCoordinateRegion(center: location, latitudinalMeters: 10000, longitudinalMeters: 10000) - let annotations = [MapPreviewPoint(name: "\(viewModel.locationName ?? "")", coordinate: location)] - Map(coordinateRegion: .constant(region), annotationItems: annotations) { - MapMarker(coordinate: $0.coordinate) - } - .frame(height: 130) - .cornerRadius(.small) - .padding(.horizontal, .xxSmall) - .padding(.bottom, .xxSmall) - .onTapGesture { - focusedField = nil - viewModel.present(.location) - } - } - } + var repeatSubtitleText: String? { + switch viewModel.repitEndRule { + case .never: + return nil + case let .occurrenceCount(count): + return count > 1 ? "With \(count) repetitions" : "With 1 repetition" + case let .endDate(date): + return "Until \(date.formatted(date: .long, time: .omitted))" } - .surfaceBorderColor(Color.surfaceSecondary) - .surfaceBorderWidth(1) - .surfaceContentMargins(.zero) - .controlRadius(.large) } - } - - var repeatSubtitleText: String? { - switch viewModel.repitEndRule { - case .never: - return nil - case let .occurrenceCount(count): - return count > 1 ? "With \(count) repetitions" : "With 1 repetition" - case let .endDate(date): - return "Until \(date.formatted(date: .long, time: .omitted))" - } - } - - var calendarButtons: some View { - HStack(spacing: .small) { - Button { - focusedField = nil - viewModel.present(.startTime) - } label: { - VStack(alignment: .leading, spacing: .xxxSmall) { - Text("Starts") - .onSurfaceMediumEmphasisForegroundColor() - .subheadline(.semibold) - - Text(startDateText) - .onSurfaceHighEmphasisForegroundColor() - .headline(.semibold) - if !isCurrentYearEvent { - Text(viewModel.dateStart.formatted(.dateTime.year())) + var calendarButtons: some View { + HStack(spacing: .small) { + Button { + focusedField = nil + viewModel.present(.startTime) + } label: { + VStack(alignment: .leading, spacing: .xxxSmall) { + Text("Starts") + .onSurfaceMediumEmphasisForegroundColor() + .subheadline(.semibold) + + Text(startDateText) .onSurfaceHighEmphasisForegroundColor() .headline(.semibold) + + if !isCurrentYearEvent { + Text(viewModel.dateStart.formatted(.dateTime.year())) + .onSurfaceHighEmphasisForegroundColor() + .headline(.semibold) + } + } + .padding(.small) + .hLeading() + .background { + RoundedRectangle(cornerRadius: .large, style: .continuous) + .fillSurfaceSecondary() } } - .padding(.small) - .hLeading() - .background { - RoundedRectangle(cornerRadius: .large, style: .continuous) - .fillSurfaceSecondary() - } - } - .buttonStyle(.scale) - - Button { - focusedField = nil - viewModel.present(.endTime) - } label: { - VStack(alignment: .leading, spacing: .xxxSmall) { - Text("Ended") - .onSurfaceMediumEmphasisForegroundColor() - .subheadline(.semibold) - - Text(endDateText) - .onSurfaceHighEmphasisForegroundColor() - .headline(.semibold) + .buttonStyle(.scale) - if !isCurrentYearEvent { - Text(viewModel.dateEnd.formatted(.dateTime.year())) + Button { + focusedField = nil + viewModel.present(.endTime) + } label: { + VStack(alignment: .leading, spacing: .xxxSmall) { + Text("Ended") + .onSurfaceMediumEmphasisForegroundColor() + .subheadline(.semibold) + + Text(endDateText) .onSurfaceHighEmphasisForegroundColor() .headline(.semibold) + + if !isCurrentYearEvent { + Text(viewModel.dateEnd.formatted(.dateTime.year())) + .onSurfaceHighEmphasisForegroundColor() + .headline(.semibold) + } + } + .padding(.small) + .hLeading() + .background { + RoundedRectangle(cornerRadius: .large, style: .continuous) + .fillSurfaceSecondary() } } - .padding(.small) - .hLeading() - .background { - RoundedRectangle(cornerRadius: .large, style: .continuous) - .fillSurfaceSecondary() - } + .buttonStyle(.scale) } - .buttonStyle(.scale) } - } - var isCurrentYearEvent: Bool { - Calendar.current.component(.year, from: viewModel.dateStart) == Calendar.current.component(.year, from: Date()) && Calendar.current.component(.year, from: viewModel.dateEnd) == Calendar.current.component(.year, from: Date()) - } + var isCurrentYearEvent: Bool { + Calendar.current.component(.year, from: viewModel.dateStart) == Calendar.current.component(.year, from: Date()) && Calendar.current.component(.year, from: viewModel.dateEnd) == Calendar.current.component(.year, from: Date()) + } - var startDateText: String { - if Calendar.current.isDateInToday(viewModel.dateStart) { - return "Today \(viewModel.dateStart.formatted(date: .omitted, time: .shortened))" - } else if Calendar.current.isDateInTomorrow(viewModel.dateStart) { - return "Tomorrow \(viewModel.dateStart.formatted(date: .omitted, time: .shortened))" - } else if Calendar.current.isDateInYesterday(viewModel.dateStart) { - return "Yesterday \(viewModel.dateStart.formatted(date: .omitted, time: .shortened))" - } else { - return "\(viewModel.dateStart.formatted(.dateTime.day().month())) \(viewModel.dateStart.formatted(date: .omitted, time: .shortened))" + var startDateText: String { + if Calendar.current.isDateInToday(viewModel.dateStart) { + return "Today \(viewModel.dateStart.formatted(date: .omitted, time: .shortened))" + } else if Calendar.current.isDateInTomorrow(viewModel.dateStart) { + return "Tomorrow \(viewModel.dateStart.formatted(date: .omitted, time: .shortened))" + } else if Calendar.current.isDateInYesterday(viewModel.dateStart) { + return "Yesterday \(viewModel.dateStart.formatted(date: .omitted, time: .shortened))" + } else { + return "\(viewModel.dateStart.formatted(.dateTime.day().month())) \(viewModel.dateStart.formatted(date: .omitted, time: .shortened))" + } } - } - var endDateText: String { - if Calendar.current.isDateInToday(viewModel.dateEnd) { - return "Today \(viewModel.dateEnd.formatted(date: .omitted, time: .shortened))" - } else if Calendar.current.isDateInTomorrow(viewModel.dateEnd) { - return "Tomorrow \(viewModel.dateEnd.formatted(date: .omitted, time: .shortened))" - } else if Calendar.current.isDateInYesterday(viewModel.dateEnd) { - return "Yesterday \(viewModel.dateEnd.formatted(date: .omitted, time: .shortened))" - } else { - return "\(viewModel.dateEnd.formatted(.dateTime.day().month())) \(viewModel.dateEnd.formatted(date: .omitted, time: .shortened))" + var endDateText: String { + if Calendar.current.isDateInToday(viewModel.dateEnd) { + return "Today \(viewModel.dateEnd.formatted(date: .omitted, time: .shortened))" + } else if Calendar.current.isDateInTomorrow(viewModel.dateEnd) { + return "Tomorrow \(viewModel.dateEnd.formatted(date: .omitted, time: .shortened))" + } else if Calendar.current.isDateInYesterday(viewModel.dateEnd) { + return "Yesterday \(viewModel.dateEnd.formatted(date: .omitted, time: .shortened))" + } else { + return "\(viewModel.dateEnd.formatted(.dateTime.day().month())) \(viewModel.dateEnd.formatted(date: .omitted, time: .shortened))" + } } - } - var bottomBar: some View { - HStack(spacing: .medium) { - Button { - Task { - focusedField = nil - viewModel.present(.location) - } - } label: { - if viewModel.isFetchUpdatePositon { - ProgressView() - } else { - IconDeprecated(.mapPin) -// Icon.Solid.NavigationandTravel.location -// .renderingMode(.template) + var bottomBar: some View { + HStack(spacing: .medium) { + Button { + Task { + focusedField = nil + viewModel.present(.location) + } + } label: { + if viewModel.isFetchUpdatePositon { + ProgressView() + } else { + IconDeprecated(.mapPin) + } } - } - .disabled(viewModel.isFetchUpdatePositon) + .disabled(viewModel.isFetchUpdatePositon) - Button { viewModel.present(.alarm) } label: { - IconDeprecated(.bell) -// Icon.Solid.UserInterface.bell -// .renderingMode(.template) - } + Button { viewModel.present(.alarm) } label: { + IconDeprecated(.bell) + } - Button { viewModel.present(.repeat) } label: { - IconDeprecated(.refresh) - } + Button { viewModel.present(.repeat) } label: { + IconDeprecated(.refresh) + } - /* - Button { viewModel.present(.attachment) } label: { - IconDeprecated(.moreHorizontal) - } - */ + /* + Button { viewModel.present(.attachment) } label: { + IconDeprecated(.moreHorizontal) + } + */ - Spacer() + Spacer() - Button { viewModel.present(.invites) } label: { - IconDeprecated(.userPlus) - } + Button { viewModel.present(.invites) } label: { + IconDeprecated(.userPlus) + } // Icon.Solid.UserInterface.plusCrFr // .renderingMode(.template) + } + .buttonStyle(.scale) + .padding(.horizontal, .medium) + .padding(.vertical, 20) + .onSurfaceMediumEmphasisForegroundColor() + .background(.ultraThinMaterial) + .overlay(alignment: .top) { + Rectangle() + .fill(Color.onSurfaceHighEmphasis.opacity(0.05)) + .frame(height: 1) + } } - .buttonStyle(.scale) - .padding(.horizontal, .medium) - .padding(.vertical, 20) - .onSurfaceMediumEmphasisForegroundColor() - .background(.ultraThinMaterial) - .overlay(alignment: .top) { - Rectangle() - .fill(Color.onSurfaceHighEmphasis.opacity(0.05)) - .frame(height: 1) - } - } - @ViewBuilder - private func placeholder() -> some View {} -} + @ViewBuilder + private func placeholder() -> some View {} + } -extension CreateEventView { - enum FocusField: Hashable { - case title - case note - case url + extension CreateEventView { + enum FocusField: Hashable { + case title + case note + case url + } } -} -struct CreateEventView_Previews: PreviewProvider { - static var previews: some View { - CreateEventView() + struct CreateEventView_Previews: PreviewProvider { + static var previews: some View { + CreateEventView() + } } -} +#endif diff --git a/Sources/OversizeCalendarKit/CreateEventScreen/CreateEventViewModel.swift b/Sources/OversizeCalendarKit/CreateEventScreen/CreateEventViewModel.swift index a7f3335..63b7a37 100644 --- a/Sources/OversizeCalendarKit/CreateEventScreen/CreateEventViewModel.swift +++ b/Sources/OversizeCalendarKit/CreateEventScreen/CreateEventViewModel.swift @@ -3,7 +3,9 @@ // CreateEventViewModel.swift // -import EventKit +#if canImport(EventKit) + import EventKit +#endif import Factory import OversizeCalendarService import OversizeCore @@ -11,173 +13,175 @@ import OversizeLocationService import OversizeModels import SwiftUI -public enum CreateEventType: Equatable { - case new(Date?, calendar: EKCalendar?) - case update(EKEvent) -} - -@MainActor -public class CreateEventViewModel: ObservableObject { - @Injected(\.calendarService) private var calendarService: CalendarService - @Injected(\.locationService) private var locationService: LocationServiceProtocol - - @Published var state = CreateEventViewModelState.initial - @Published var sheet: CreateEventViewModel.Sheet? = nil - @Published var isFetchUpdatePositon: Bool = .init(false) - - @Published var title: String = .init() - @Published var note: String = .init() - @Published var url: String = .init() - @Published var dateStart: Date = .init() - @Published var dateEnd: Date = .init().halfHour - @Published var isAllDay: Bool = .init(false) - @Published var calendar: EKCalendar? - @Published var calendars: [EKCalendar] = .init() - @Published var sourses: [EKSource] = .init() - @Published var locationName: String? - @Published var location: CLLocationCoordinate2D? - @Published var repitRule: CalendarEventRecurrenceRules = .never - @Published var repitEndRule: CalendarEventEndRecurrenceRules = .never - @Published var alarms: [CalendarAlertsTimes] = .init() - @Published var members: [String] = .init() - @Published var span: EKSpan? - - let type: CreateEventType - - var isLocationSelected: Bool { - location != nil +#if !os(tvOS) + public enum CreateEventType: Equatable { + case new(Date?, calendar: EKCalendar?) + case update(EKEvent) } - public init(_ type: CreateEventType) { - self.type = type - setEvent(type: type) - } + @MainActor + public class CreateEventViewModel: ObservableObject { + @Injected(\.calendarService) private var calendarService: CalendarService + @Injected(\.locationService) private var locationService: LocationServiceProtocol + + @Published var state = CreateEventViewModelState.initial + @Published var sheet: CreateEventViewModel.Sheet? = nil + @Published var isFetchUpdatePositon: Bool = .init(false) + + @Published var title: String = .init() + @Published var note: String = .init() + @Published var url: String = .init() + @Published var dateStart: Date = .init() + @Published var dateEnd: Date = .init().halfHour + @Published var isAllDay: Bool = .init(false) + @Published var calendar: EKCalendar? + @Published var calendars: [EKCalendar] = .init() + @Published var sourses: [EKSource] = .init() + @Published var locationName: String? + @Published var location: CLLocationCoordinate2D? + @Published var repitRule: CalendarEventRecurrenceRules = .never + @Published var repitEndRule: CalendarEventEndRecurrenceRules = .never + @Published var alarms: [CalendarAlertsTimes] = .init() + @Published var members: [String] = .init() + @Published var span: EKSpan? + + let type: CreateEventType + + var isLocationSelected: Bool { + location != nil + } - func setEvent(type: CreateEventType) { - switch type { - case let .new(date, calendar): - if let date { - dateStart = date - dateEnd = date.halfHour - } - if let calendar { - self.calendar = calendar - } - case let .update(event): - title = event.title - note = event.notes ?? "" - url = event.url?.absoluteString ?? "" - dateStart = event.startDate - dateEnd = event.endDate - isAllDay = event.isAllDay - calendar = event.calendar - locationName = event.location - if let coordinate = event.structuredLocation?.geoLocation?.coordinate { - location = coordinate + public init(_ type: CreateEventType) { + self.type = type + setEvent(type: type) + } + + func setEvent(type: CreateEventType) { + switch type { + case let .new(date, calendar): + if let date { + dateStart = date + dateEnd = date.halfHour + } + if let calendar { + self.calendar = calendar + } + case let .update(event): + title = event.title + note = event.notes ?? "" + url = event.url?.absoluteString ?? "" + dateStart = event.startDate + dateEnd = event.endDate + isAllDay = event.isAllDay + calendar = event.calendar + locationName = event.location + if let coordinate = event.structuredLocation?.geoLocation?.coordinate { + location = coordinate + } + if let rule = event.recurrenceRules?.first { + repitRule = rule.calendarRecurrenceRule + repitEndRule = rule.recurrenceEnd?.calendarEndRecurrenceRule ?? .never + } + if let eventAlarms = event.alarms { + alarms = eventAlarms.compactMap { $0.calendarAlert } + } + if let attendees = event.attendees { + members = attendees.compactMap { $0.url.absoluteString } + } } - if let rule = event.recurrenceRules?.first { - repitRule = rule.calendarRecurrenceRule - repitEndRule = rule.recurrenceEnd?.calendarEndRecurrenceRule ?? .never + } + + func fetchData() async { + state = .loading + async let calendarsResult = await calendarService.fetchCalendars() + switch await calendarsResult { + case let .success(data): + log("✅ EKCalendars fetched") + calendars = data + case let .failure(error): + log("❌ EKCalendars not fetched (\(error.title))") + state = .error(error) } - if let eventAlarms = event.alarms { - alarms = eventAlarms.compactMap { $0.calendarAlert } + async let soursesResult = await calendarService.fetchSourses() + switch await soursesResult { + case let .success(data): + log("✅ EKSource fetched") + sourses = data + case let .failure(error): + log("❌ EKSource not fetched (\(error.title))") + state = .error(error) } - if let attendees = event.attendees { - members = attendees.compactMap { $0.url.absoluteString } + if case let .new(_, calendar) = type, calendar == nil { + let result = await calendarService.fetchDefaultCalendar() + switch result { + case let .success(calendar): + self.calendar = calendar + case let .failure(error): + log("❌ Default calendar not fetched (\(error.title))") + } } } - } - func fetchData() async { - state = .loading - async let calendarsResult = await calendarService.fetchCalendars() - switch await calendarsResult { - case let .success(data): - log("✅ EKCalendars fetched") - calendars = data - case let .failure(error): - log("❌ EKCalendars not fetched (\(error.title))") - state = .error(error) - } - async let soursesResult = await calendarService.fetchSourses() - switch await soursesResult { - case let .success(data): - log("✅ EKSource fetched") - sourses = data - case let .failure(error): - log("❌ EKSource not fetched (\(error.title))") - state = .error(error) - } - if case let .new(_, calendar) = type, calendar == nil { - let result = await calendarService.fetchDefaultCalendar() + func save() async -> Result { + var oldEvent: EKEvent? + + if case let .update(event) = type { + oldEvent = event + } + + let result = await calendarService.createEvent( + event: oldEvent, + title: title, + notes: note, + startDate: dateStart, + endDate: dateEnd, + calendar: calendar, + isAllDay: isAllDay, + location: locationName, + structuredLocation: getEKStructuredLocation(), + alarms: alarms, + url: URL(string: url), + memberEmails: members, + recurrenceRules: repitRule, + recurrenceEndRules: repitEndRule, + span: span ?? .thisEvent + ) switch result { - case let .success(calendar): - self.calendar = calendar + case let .success(data): + log("✅ EKEvent saved") + return .success(data) case let .failure(error): - log("❌ Default calendar not fetched (\(error.title))") + log("❌ EKEvent not saved (\(error.title))") + return .failure(error) } } - } - func save() async -> Result { - var oldEvent: EKEvent? - - if case let .update(event) = type { - oldEvent = event - } - - let result = await calendarService.createEvent( - event: oldEvent, - title: title, - notes: note, - startDate: dateStart, - endDate: dateEnd, - calendar: calendar, - isAllDay: isAllDay, - location: locationName, - structuredLocation: getEKStructuredLocation(), - alarms: alarms, - url: URL(string: url), - memberEmails: members, - recurrenceRules: repitRule, - recurrenceEndRules: repitEndRule, - span: span ?? .thisEvent - ) - switch result { - case let .success(data): - log("✅ EKEvent saved") - return .success(data) - case let .failure(error): - log("❌ EKEvent not saved (\(error.title))") - return .failure(error) + func getEKStructuredLocation() -> EKStructuredLocation? { + if let location { + let structuredLocation: EKStructuredLocation? + let location = CLLocation(latitude: location.latitude, longitude: location.longitude) + structuredLocation = EKStructuredLocation(title: locationName ?? "") // same title with ekEvent.location + structuredLocation?.geoLocation = location + return structuredLocation + } else { + return nil + } } - } - func getEKStructuredLocation() -> EKStructuredLocation? { - if let location { - let structuredLocation: EKStructuredLocation? - let location = CLLocation(latitude: location.latitude, longitude: location.longitude) - structuredLocation = EKStructuredLocation(title: locationName ?? "") // same title with ekEvent.location - structuredLocation?.geoLocation = location - return structuredLocation - } else { - return nil + func updateCurrentPosition() async throws { + isFetchUpdatePositon = true + let currentPosition = try await locationService.currentLocation() + guard let newLocation = currentPosition else { return } + location = newLocation + log("📍 Location: \(newLocation.latitude), \(newLocation.longitude)") + isFetchUpdatePositon = false } } - func updateCurrentPosition() async throws { - isFetchUpdatePositon = true - let currentPosition = try await locationService.currentLocation() - guard let newLocation = currentPosition else { return } - location = newLocation - log("📍 Location: \(newLocation.latitude), \(newLocation.longitude)") - isFetchUpdatePositon = false + public enum CreateEventViewModelState { + case initial + case loading + case result([EKEvent]) + case error(AppError) } -} - -public enum CreateEventViewModelState { - case initial - case loading - case result([EKEvent]) - case error(AppError) -} +#endif diff --git a/Sources/OversizeCalendarKit/CreateEventScreen/CreateEventViewSheet.swift b/Sources/OversizeCalendarKit/CreateEventScreen/CreateEventViewSheet.swift index 5136669..e7096ce 100644 --- a/Sources/OversizeCalendarKit/CreateEventScreen/CreateEventViewSheet.swift +++ b/Sources/OversizeCalendarKit/CreateEventScreen/CreateEventViewSheet.swift @@ -3,112 +3,116 @@ // CreateEventViewSheet.swift // -import EventKit +#if canImport(EventKit) + import EventKit +#endif import OversizeComponents import OversizeContactsKit import OversizeLocationKit import OversizeUI import SwiftUI -public extension CreateEventViewModel { - func present(_ sheet: CreateEventViewModel.Sheet) { - self.sheet = sheet - } +#if !os(tvOS) + public extension CreateEventViewModel { + func present(_ sheet: CreateEventViewModel.Sheet) { + self.sheet = sheet + } - func close() { - sheet = nil + func close() { + sheet = nil + } } -} - -public extension CreateEventViewModel { - enum Sheet { - case startTime - case endTime - case attachment - case calendar - case location - case `repeat` - case alarm - case invites - case span - } // attachment, alert, invitees -} -extension CreateEventViewModel.Sheet: Identifiable { - public var id: String { - switch self { - case .startTime: - return "startTime" - case .endTime: - return "endTime" - case .attachment: - return "attachment" - case .calendar: - return "calendar" - case .location: - return "location" - case .repeat: - return "repeat" - case .alarm: - return "alarm" - case .invites: - return "alarm" - case .span: - return "span" - } + public extension CreateEventViewModel { + enum Sheet { + case startTime + case endTime + case attachment + case calendar + case location + case `repeat` + case alarm + case invites + case span + } // attachment, alert, invitees } -} -public extension CreateEventView { - func resolveSheet(sheet: CreateEventViewModel.Sheet) -> some View { - Group { - switch sheet { + extension CreateEventViewModel.Sheet: Identifiable { + public var id: String { + switch self { case .startTime: - #if os(iOS) - DatePickerSheet(title: "Starts time", selection: $viewModel.dateStart) - .onDisappear { - if viewModel.dateStart > viewModel.dateEnd { - viewModel.dateEnd = viewModel.dateStart.halfHour - } - } - .presentationDetents([.height(500)]) - #else - EmptyView() - #endif + return "startTime" case .endTime: - #if os(iOS) - DatePickerSheet(title: "Ends time", selection: $viewModel.dateEnd) - .datePickerMinimumDate(viewModel.dateStart.minute) - .presentationDetents([.height(500)]) - #else - EmptyView() - #endif + return "endTime" case .attachment: - AttachmentView() - .presentationDetents([.height(270)]) + return "attachment" case .calendar: - CalendarPicker(selection: $viewModel.calendar, calendars: viewModel.calendars, sourses: viewModel.sourses) - .presentationDetents([.large]) + return "calendar" case .location: - AddressPicker(address: $viewModel.locationName, location: $viewModel.location) - .interactiveDismissDisabled(true) - .presentationDetents([.large]) + return "location" case .repeat: - RepeatPicker(selectionRule: $viewModel.repitRule, selectionEndRule: $viewModel.repitEndRule) - + return "repeat" case .alarm: - AlarmPicker(selection: $viewModel.alarms) - .presentationDetents([.height(630), .large]) - .presentationDragIndicator(.hidden) + return "alarm" case .invites: - EmailPickerView(selection: $viewModel.members) - .presentationDetents([.large]) - .interactiveDismissDisabled(true) + return "alarm" case .span: - SaveForView(selection: $viewModel.span) - .presentationDetents([.height(270)]) + return "span" + } + } + } + + public extension CreateEventView { + func resolveSheet(sheet: CreateEventViewModel.Sheet) -> some View { + Group { + switch sheet { + case .startTime: + #if os(iOS) + DatePickerSheet(title: "Starts time", selection: $viewModel.dateStart) + .onDisappear { + if viewModel.dateStart > viewModel.dateEnd { + viewModel.dateEnd = viewModel.dateStart.halfHour + } + } + .presentationDetents([.height(500)]) + #else + EmptyView() + #endif + case .endTime: + #if os(iOS) + DatePickerSheet(title: "Ends time", selection: $viewModel.dateEnd) + .datePickerMinimumDate(viewModel.dateStart.minute) + .presentationDetents([.height(500)]) + #else + EmptyView() + #endif + case .attachment: + AttachmentView() + .presentationDetents([.height(270)]) + case .calendar: + CalendarPicker(selection: $viewModel.calendar, calendars: viewModel.calendars, sourses: viewModel.sourses) + .presentationDetents([.large]) + case .location: + AddressPicker(address: $viewModel.locationName, location: $viewModel.location) + .interactiveDismissDisabled(true) + .presentationDetents([.large]) + case .repeat: + RepeatPicker(selectionRule: $viewModel.repitRule, selectionEndRule: $viewModel.repitEndRule) + + case .alarm: + AlarmPicker(selection: $viewModel.alarms) + .presentationDetents([.height(630), .large]) + .presentationDragIndicator(.hidden) + case .invites: + EmailPickerView(selection: $viewModel.members) + .presentationDetents([.large]) + .interactiveDismissDisabled(true) + case .span: + SaveForView(selection: $viewModel.span) + .presentationDetents([.height(270)]) + } } + .systemServices() } - .systemServices() } -} +#endif diff --git a/Sources/OversizeCalendarKit/CreateEventScreen/SaveForView/SaveForView.swift b/Sources/OversizeCalendarKit/CreateEventScreen/SaveForView/SaveForView.swift index b8ee9d7..ba4f08f 100644 --- a/Sources/OversizeCalendarKit/CreateEventScreen/SaveForView/SaveForView.swift +++ b/Sources/OversizeCalendarKit/CreateEventScreen/SaveForView/SaveForView.swift @@ -3,46 +3,50 @@ // SaveForView.swift // -import EventKit +#if canImport(EventKit) + import EventKit +#endif import OversizeUI import SwiftUI -public struct SaveForView: View { - @Environment(\.dismiss) var dismiss - @Binding private var span: EKSpan? +#if !os(tvOS) + public struct SaveForView: View { + @Environment(\.dismiss) var dismiss + @Binding private var span: EKSpan? - public init(selection: Binding) { - _span = selection - } + public init(selection: Binding) { + _span = selection + } - public var body: some View { - PageView("This is repeating event") { - SectionView { - VStack(spacing: .zero) { - Row("Save for this event only") { - span = .thisEvent - dismiss() - } leading: { - Image.Date.calendar - .renderingMode(.template) - .foregroundColor(.onSurfaceHighEmphasis) - } + public var body: some View { + PageView("This is repeating event") { + SectionView { + VStack(spacing: .zero) { + Row("Save for this event only") { + span = .thisEvent + dismiss() + } leading: { + Image.Date.calendar + .renderingMode(.template) + .foregroundColor(.onSurfaceHighEmphasis) + } - Row("Save for feature events") { - span = .futureEvents - dismiss() - } leading: { - Image.Base.calendar - .renderingMode(.template) - .foregroundColor(.onSurfaceHighEmphasis) + Row("Save for feature events") { + span = .futureEvents + dismiss() + } leading: { + Image.Base.calendar + .renderingMode(.template) + .foregroundColor(.onSurfaceHighEmphasis) + } } } + .surfaceContentRowMargins() + } + .backgroundSecondary() + .leadingBar { + BarButton(.close) } - .surfaceContentRowMargins() - } - .backgroundSecondary() - .leadingBar { - BarButton(.close) } } -} +#endif diff --git a/Sources/OversizeCalendarKit/Pickers/AlertPicker.swift b/Sources/OversizeCalendarKit/Pickers/AlertPicker.swift index 68fbfb8..f31672c 100644 --- a/Sources/OversizeCalendarKit/Pickers/AlertPicker.swift +++ b/Sources/OversizeCalendarKit/Pickers/AlertPicker.swift @@ -3,51 +3,55 @@ // AlertPicker.swift // -import EventKit +#if canImport(EventKit) + import EventKit +#endif import OversizeCalendarService import OversizeUI import SwiftUI -public struct AlarmPicker: View { - @Environment(\.dismiss) var dismiss - @Binding private var selection: [CalendarAlertsTimes] - @State private var selectedAlerts: [CalendarAlertsTimes] = [] +#if !os(tvOS) + public struct AlarmPicker: View { + @Environment(\.dismiss) var dismiss + @Binding private var selection: [CalendarAlertsTimes] + @State private var selectedAlerts: [CalendarAlertsTimes] = [] - public init(selection: Binding<[CalendarAlertsTimes]>) { - _selection = selection - _selectedAlerts = State(wrappedValue: selection.wrappedValue) - } + public init(selection: Binding<[CalendarAlertsTimes]>) { + _selection = selection + _selectedAlerts = State(wrappedValue: selection.wrappedValue) + } - public var body: some View { - PageView("Alarm") { - SectionView { - VStack(spacing: .zero) { - ForEach(CalendarAlertsTimes.allCases) { alert in - Checkbox(alert.title, isOn: .constant((selectedAlerts.first { $0.id == alert.id } != nil) ? true : false)) { - if !selectedAlerts.isEmpty, let _ = selectedAlerts.first(where: { $0.id == alert.id }) { - selectedAlerts.remove(alert) - } else { - selectedAlerts.append(alert) + public var body: some View { + PageView("Alarm") { + SectionView { + VStack(spacing: .zero) { + ForEach(CalendarAlertsTimes.allCases) { alert in + Checkbox(alert.title, isOn: .constant((selectedAlerts.first { $0.id == alert.id } != nil) ? true : false)) { + if !selectedAlerts.isEmpty, let _ = selectedAlerts.first(where: { $0.id == alert.id }) { + selectedAlerts.remove(alert) + } else { + selectedAlerts.append(alert) + } } } } } + .surfaceContentRowMargins() + } + .backgroundSecondary() + .leadingBar { + BarButton(.close) + } + .trailingBar { + BarButton(.accent("Done", action: { + selection = selectedAlerts + dismiss() + })) + .disabled(selectedAlerts.isEmpty) } - .surfaceContentRowMargins() - } - .backgroundSecondary() - .leadingBar { - BarButton(.close) - } - .trailingBar { - BarButton(.accent("Done", action: { - selection = selectedAlerts - dismiss() - })) - .disabled(selectedAlerts.isEmpty) } } -} +#endif // struct AlertPicker_Previews: PreviewProvider { // static var previews: some View { diff --git a/Sources/OversizeCalendarKit/Pickers/CalendarPicker.swift b/Sources/OversizeCalendarKit/Pickers/CalendarPicker.swift index 173685e..8244d84 100644 --- a/Sources/OversizeCalendarKit/Pickers/CalendarPicker.swift +++ b/Sources/OversizeCalendarKit/Pickers/CalendarPicker.swift @@ -3,66 +3,70 @@ // CalendarPicker.swift // -import EventKit +#if canImport(EventKit) + import EventKit +#endif import OversizeUI import SwiftUI -public struct CalendarPicker: View { - @Environment(\.dismiss) var dismiss +#if !os(tvOS) + public struct CalendarPicker: View { + @Environment(\.dismiss) var dismiss - @Binding private var selection: EKCalendar? + @Binding private var selection: EKCalendar? - private let calendars: [EKCalendar] + private let calendars: [EKCalendar] - private let sourses: [EKSource] + private let sourses: [EKSource] - private let closable: Bool + private let closable: Bool - public init(selection: Binding, calendars: [EKCalendar], sourses: [EKSource], closable: Bool = true) { - _selection = selection - self.calendars = calendars - self.sourses = sourses - self.closable = closable - } + public init(selection: Binding, calendars: [EKCalendar], sourses: [EKSource], closable: Bool = true) { + _selection = selection + self.calendars = calendars + self.sourses = sourses + self.closable = closable + } - public var body: some View { - PageView("Calendar") { - ForEach(sourses, id: \.sourceIdentifier) { source in - let filtredCalendar: [EKCalendar] = calendars.filter { $0.source.sourceIdentifier == source.sourceIdentifier && $0.allowsContentModifications } - if !filtredCalendar.isEmpty { - calendarSection(source: source, calendars: filtredCalendar) + public var body: some View { + PageView("Calendar") { + ForEach(sourses, id: \.sourceIdentifier) { source in + let filtredCalendar: [EKCalendar] = calendars.filter { $0.source.sourceIdentifier == source.sourceIdentifier && $0.allowsContentModifications } + if !filtredCalendar.isEmpty { + calendarSection(source: source, calendars: filtredCalendar) + } } } + .backgroundSecondary() + .leadingBar { + BarButton(closable ? .close : .back) + } } - .backgroundSecondary() - .leadingBar { - BarButton(closable ? .close : .back) - } - } - func calendarSection(source: EKSource, calendars: [EKCalendar]) -> some View { - SectionView(source.title) { - VStack(spacing: .zero) { - ForEach(calendars, id: \.calendarIdentifier) { calendar in - Radio(isOn: selection?.calendarIdentifier == calendar.calendarIdentifier) { - selection = calendar - dismiss() - } label: { - Row(calendar.title) { - Circle() - .fill(Color(calendar.cgColor)) - .frame(width: 16, height: 16) + func calendarSection(source: EKSource, calendars: [EKCalendar]) -> some View { + SectionView(source.title) { + VStack(spacing: .zero) { + ForEach(calendars, id: \.calendarIdentifier) { calendar in + Radio(isOn: selection?.calendarIdentifier == calendar.calendarIdentifier) { + selection = calendar + dismiss() + } label: { + Row(calendar.title) { + Circle() + .fill(Color(calendar.cgColor)) + .frame(width: 16, height: 16) + } } } } } + .surfaceContentRowMargins() } - .surfaceContentRowMargins() } -} -struct CalendarPicker_Previews: PreviewProvider { - static var previews: some View { - CalendarPicker(selection: .constant(nil), calendars: [], sourses: []) + struct CalendarPicker_Previews: PreviewProvider { + static var previews: some View { + CalendarPicker(selection: .constant(nil), calendars: [], sourses: []) + } } -} +#endif diff --git a/Sources/OversizeCalendarKit/Pickers/RepeatPicker.swift b/Sources/OversizeCalendarKit/Pickers/RepeatPicker.swift index ec7b5d2..71fd9d4 100644 --- a/Sources/OversizeCalendarKit/Pickers/RepeatPicker.swift +++ b/Sources/OversizeCalendarKit/Pickers/RepeatPicker.swift @@ -3,132 +3,130 @@ // RepeatPicker.swift // -import EventKit +#if canImport(EventKit) + import EventKit +#endif import OversizeCalendarService import OversizeUI import SwiftUI -public struct RepeatPicker: View { - @Environment(\.dismiss) private var dismiss +#if !os(tvOS) + public struct RepeatPicker: View { + @Environment(\.dismiss) private var dismiss - @Binding private var selectionRule: CalendarEventRecurrenceRules - @Binding private var selectionEndRule: CalendarEventEndRecurrenceRules + @Binding private var selectionRule: CalendarEventRecurrenceRules + @Binding private var selectionEndRule: CalendarEventEndRecurrenceRules - @State private var rule: CalendarEventRecurrenceRules - @State private var endRule: CalendarEventEndRecurrenceRules + @State private var rule: CalendarEventRecurrenceRules + @State private var endRule: CalendarEventEndRecurrenceRules - @State private var endDate: Date = .init() - @State private var repeatCount: String = "1" - @FocusState private var isFocusedRepitCount: Bool + @State private var endDate: Date = .init() + @State private var repeatCount: String = "1" + @FocusState private var isFocusedRepitCount: Bool - public init(selectionRule: Binding, selectionEndRule: Binding) { - _selectionRule = selectionRule - _selectionEndRule = selectionEndRule - _rule = State(wrappedValue: selectionRule.wrappedValue) - _endRule = State(wrappedValue: selectionEndRule.wrappedValue) - } + public init(selectionRule: Binding, selectionEndRule: Binding) { + _selectionRule = selectionRule + _selectionEndRule = selectionEndRule + _rule = State(wrappedValue: selectionRule.wrappedValue) + _endRule = State(wrappedValue: selectionEndRule.wrappedValue) + } - public var body: some View { - ScrollViewReader { scrollView in - PageView("Repeat") { - SectionView { - VStack(spacing: .zero) { - ForEach(CalendarEventRecurrenceRules.allCases) { rule in - Radio(isOn: self.rule.id == rule.id) { - withAnimation { - self.rule = rule + public var body: some View { + ScrollViewReader { scrollView in + PageView("Repeat") { + SectionView { + VStack(spacing: .zero) { + ForEach(CalendarEventRecurrenceRules.allCases) { rule in + Radio(isOn: self.rule.id == rule.id) { + withAnimation { + self.rule = rule + } + } label: { + Row(rule.title) } - } label: { - Row(rule.title) } } } - } - if rule != .never { - SectionView("End Repeat") { - VStack(spacing: .zero) { - ForEach(CalendarEventEndRecurrenceRules.allCases) { rule in - VStack(spacing: .xxSmall) { - Radio(isOn: endRule.id == rule.id) { - endRule = rule - if case .occurrenceCount = endRule { - isFocusedRepitCount = true - scrollView.scrollTo(rule.id) - } + if rule != .never { + SectionView("End Repeat") { + VStack(spacing: .zero) { + ForEach(CalendarEventEndRecurrenceRules.allCases) { rule in + VStack(spacing: .xxSmall) { + Radio(isOn: endRule.id == rule.id) { + endRule = rule + if case .occurrenceCount = endRule { + isFocusedRepitCount = true + scrollView.scrollTo(rule.id) + } - if case .endDate = endRule { - isFocusedRepitCount = true - scrollView.scrollTo(rule.id) + if case .endDate = endRule { + isFocusedRepitCount = true + scrollView.scrollTo(rule.id) + } + } label: { + Row(rule.title) } - } label: { - Row(rule.title) - } - if endRule.id == rule.id { - repartPicker(rules: rule) - .padding(.horizontal, .medium) - .padding(.bottom, .small) + if endRule.id == rule.id { + repartPicker(rules: rule) + .padding(.horizontal, .medium) + .padding(.bottom, .small) + } } } } } + .transition(.move(edge: .top)) } - .transition(.move(edge: .top)) } + .backgroundSecondary() + .leadingBar { + BarButton(.close) + } + .trailingBar { + BarButton(.accent("Done", action: { + selectionRule = rule + selectionEndRule = endRule + dismiss() + })) + .disabled(rule == .never) + } + .surfaceContentRowMargins() } - .backgroundSecondary() - .leadingBar { - BarButton(.close) - } - .trailingBar { - BarButton(.accent("Done", action: { - selectionRule = rule - selectionEndRule = endRule - dismiss() - })) - .disabled(rule == .never) - } - .surfaceContentRowMargins() + .presentationDetents(rule == .never ? [.height(630), .large] : [.large]) + .presentationDragIndicator(.hidden) } - .presentationDetents(rule == .never ? [.height(630), .large] : [.large]) - .presentationDragIndicator(.hidden) - } - @ViewBuilder - func repartPicker(rules: CalendarEventEndRecurrenceRules) -> some View { - switch rules { - case .never: - EmptyView() - case .occurrenceCount: - TextField("Number of repetitions", text: Binding(get: { - repeatCount - }, set: { newValue in - repeatCount = newValue - endRule = .occurrenceCount(Int(newValue) ?? 1) - })) - #if os(iOS) - .keyboardType(.numberPad) - #endif - .textFieldStyle(DefaultPlaceholderTextFieldStyle()) - .focused($isFocusedRepitCount) - case .endDate: - DatePicker("Date", selection: Binding(get: { - endDate - }, set: { newDate in - endDate = newDate - endRule = .endDate(newDate) - })) - #if os(iOS) - .datePickerStyle(.wheel) - #endif - .labelsHidden() + @ViewBuilder + func repartPicker(rules: CalendarEventEndRecurrenceRules) -> some View { + switch rules { + case .never: + EmptyView() + case .occurrenceCount: + TextField("Number of repetitions", text: Binding(get: { + repeatCount + }, set: { newValue in + repeatCount = newValue + endRule = .occurrenceCount(Int(newValue) ?? 1) + })) + #if os(iOS) + .keyboardType(.numberPad) + #endif + .textFieldStyle(DefaultPlaceholderTextFieldStyle()) + .focused($isFocusedRepitCount) + case .endDate: + DatePicker("Date", selection: Binding(get: { + endDate + }, set: { newDate in + endDate = newDate + endRule = .endDate(newDate) + })) + #if os(iOS) + .datePickerStyle(.wheel) + #endif + .labelsHidden() + } } } -} - -// struct RepeatPicker_Previews: PreviewProvider { -// static var previews: some View { -// RepeatPicker() -// } -// } +#endif diff --git a/Sources/OversizeContactsKit/AttendeesList/AttendeesView.swift b/Sources/OversizeContactsKit/AttendeesList/AttendeesView.swift index 3125879..6af1afd 100644 --- a/Sources/OversizeContactsKit/AttendeesList/AttendeesView.swift +++ b/Sources/OversizeContactsKit/AttendeesList/AttendeesView.swift @@ -3,8 +3,10 @@ // AttendeesView.swift // -import Contacts -import EventKit +#if canImport(Contacts) && canImport(EventKit) + import Contacts + import EventKit +#endif import OversizeCalendarService import OversizeContactsService import OversizeCore @@ -13,81 +15,83 @@ import OversizeLocalizable import OversizeUI import SwiftUI -public struct AttendeesView: View { - @StateObject var viewModel: AttendeesViewModel - @Environment(\.dismiss) var dismiss +#if !os(tvOS) + public struct AttendeesView: View { + @StateObject var viewModel: AttendeesViewModel + @Environment(\.dismiss) var dismiss - public init(event: EKEvent) { - _viewModel = StateObject(wrappedValue: AttendeesViewModel(event: event)) - } + public init(event: EKEvent) { + _viewModel = StateObject(wrappedValue: AttendeesViewModel(event: event)) + } - public var body: some View { - PageView("Invitees") { - Group { - switch viewModel.state { - case .initial: - placeholder() - .onAppear { - Task { - await viewModel.fetchData() + public var body: some View { + PageView("Invitees") { + Group { + switch viewModel.state { + case .initial: + placeholder() + .onAppear { + Task { + await viewModel.fetchData() + } } - } - case .loading: - placeholder() - case let .result(data): - content(data) - case let .error(error): - ErrorView(error) + case .loading: + placeholder() + case let .result(data): + content(data) + case let .error(error): + ErrorView(error) + } } } + .leadingBar { + BarButton(.close) + } } - .leadingBar { - BarButton(.close) - } - } - @ViewBuilder - private func content(_: [CNContact]) -> some View { - if let attendees = viewModel.event.attendees { - VStack(spacing: .zero) { - if let organizer = viewModel.event.organizer { - Row(organizer.name ?? organizer.url.absoluteString, subtitle: "Organizer") { - userAvatarView(participant: organizer) + @ViewBuilder + private func content(_: [CNContact]) -> some View { + if let attendees = viewModel.event.attendees { + VStack(spacing: .zero) { + if let organizer = viewModel.event.organizer { + Row(organizer.name ?? organizer.url.absoluteString, subtitle: "Organizer") { + userAvatarView(participant: organizer) + } } - } - ForEach(attendees, id: \.self) { attender in - Row(attender.name ?? attender.url.absoluteString, subtitle: attender.participantRole.title) { - userAvatarView(participant: attender) + ForEach(attendees, id: \.self) { attender in + Row(attender.name ?? attender.url.absoluteString, subtitle: attender.participantRole.title) { + userAvatarView(participant: attender) + } } } } } - } - func userAvatarView(participant: EKParticipant) -> some View { - ZStack(alignment: .bottomTrailing) { - Avatar(firstName: participant.name ?? participant.url.absoluteString) - .controlSize(.regular) + func userAvatarView(participant: EKParticipant) -> some View { + ZStack(alignment: .bottomTrailing) { + Avatar(firstName: participant.name ?? participant.url.absoluteString) + .controlSize(.regular) - ZStack { - Circle() - .fill(participant.color) - .frame(width: 16, height: 16) - .background { - Circle() - .stroke(lineWidth: 4) - .fillBackgroundPrimary() - } - Image(systemName: participant.symbolName) - .onPrimaryHighEmphasisForegroundColor() - .font(.system(size: 9, weight: .black)) + ZStack { + Circle() + .fill(participant.color) + .frame(width: 16, height: 16) + .background { + Circle() + .stroke(lineWidth: 4) + .fillBackgroundPrimary() + } + Image(systemName: participant.symbolName) + .onPrimaryHighEmphasisForegroundColor() + .font(.system(size: 9, weight: .black)) + } } } - } - @ViewBuilder - private func placeholder() -> some View { - LoaderOverlayView() + @ViewBuilder + private func placeholder() -> some View { + LoaderOverlayView() + } } -} +#endif diff --git a/Sources/OversizeContactsKit/AttendeesList/AttendeesViewModel.swift b/Sources/OversizeContactsKit/AttendeesList/AttendeesViewModel.swift index 3b06806..0dfa02b 100644 --- a/Sources/OversizeContactsKit/AttendeesList/AttendeesViewModel.swift +++ b/Sources/OversizeContactsKit/AttendeesList/AttendeesViewModel.swift @@ -3,61 +3,65 @@ // AttendeesViewModel.swift // -import Contacts -import EventKit +#if canImport(Contacts) && canImport(EventKit) + import Contacts + import EventKit +#endif import Factory import OversizeContactsService import OversizeCore import OversizeModels import SwiftUI -@MainActor -class AttendeesViewModel: ObservableObject { - @Injected(\.contactsService) private var contactsService: ContactsService - @Published var state = AttendeesViewModelState.initial - @Published var searchText: String = .init() +#if !os(tvOS) + @MainActor + class AttendeesViewModel: ObservableObject { + @Injected(\.contactsService) private var contactsService: ContactsService + @Published var state = AttendeesViewModelState.initial + @Published var searchText: String = .init() - let event: EKEvent + let event: EKEvent - init(event: EKEvent) { - self.event = event - } + init(event: EKEvent) { + self.event = event + } - func fetchData() async { - state = .loading - let _ = await contactsService.requestAccess() - do { - let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactEmailAddressesKey, CNContactThumbnailImageDataKey] - let result = try await contactsService.fetchContacts(keysToFetch: keys as [CNKeyDescriptor]) - switch result { - case let .success(data): - log("✅ CNContact fetched") - state = .result(data) - case let .failure(error): - log("❌ CNContact not fetched (\(error.title))") - state = .error(error) + func fetchData() async { + state = .loading + let _ = await contactsService.requestAccess() + do { + let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactEmailAddressesKey, CNContactThumbnailImageDataKey] + let result = try await contactsService.fetchContacts(keysToFetch: keys as [CNKeyDescriptor]) + switch result { + case let .success(data): + log("✅ CNContact fetched") + state = .result(data) + case let .failure(error): + log("❌ CNContact not fetched (\(error.title))") + state = .error(error) + } + } catch { + state = .error(.custom(title: "Not contacts")) } - } catch { - state = .error(.custom(title: "Not contacts")) } - } - func getContactFromEmail(email: String, contacts: [CNContact]) -> CNContact? { - for contact in contacts where !contact.emailAddresses.isEmpty { - for emailAddress in contact.emailAddresses { - let emailAddressString = emailAddress.value as String - if emailAddressString == email { - return contact + func getContactFromEmail(email: String, contacts: [CNContact]) -> CNContact? { + for contact in contacts where !contact.emailAddresses.isEmpty { + for emailAddress in contact.emailAddresses { + let emailAddressString = emailAddress.value as String + if emailAddressString == email { + return contact + } } } + return nil } - return nil } -} -enum AttendeesViewModelState { - case initial - case loading - case result([CNContact]) - case error(AppError) -} + enum AttendeesViewModelState { + case initial + case loading + case result([CNContact]) + case error(AppError) + } +#endif diff --git a/Sources/OversizeContactsKit/ContactsLists/ContactsListsView.swift b/Sources/OversizeContactsKit/ContactsLists/ContactsListsView.swift index c1d8c82..11d868c 100644 --- a/Sources/OversizeContactsKit/ContactsLists/ContactsListsView.swift +++ b/Sources/OversizeContactsKit/ContactsLists/ContactsListsView.swift @@ -3,7 +3,9 @@ // ContactsListsView.swift // -import Contacts +#if canImport(Contacts) + import Contacts +#endif import OversizeComponents import OversizeCore import OversizeKit @@ -11,83 +13,85 @@ import OversizeLocalizable import OversizeUI import SwiftUI -public struct ContactsListsView: View { - @StateObject var viewModel: ContactsListsViewModel - @Environment(\.dismiss) var dismiss - @Binding private var emails: [String] +#if !os(tvOS) + public struct ContactsListsView: View { + @StateObject var viewModel: ContactsListsViewModel + @Environment(\.dismiss) var dismiss + @Binding private var emails: [String] - public init(emails: Binding<[String]>) { - _viewModel = StateObject(wrappedValue: ContactsListsViewModel()) - _emails = emails - } + public init(emails: Binding<[String]>) { + _viewModel = StateObject(wrappedValue: ContactsListsViewModel()) + _emails = emails + } - public var body: some View { - PageView("") { - Group { - switch viewModel.state { - case .initial: - placeholder() - case .loading: - placeholder() - case let .result(data): - content(data: data) - case let .error(error): - ErrorView(error) + public var body: some View { + PageView("") { + Group { + switch viewModel.state { + case .initial: + placeholder() + case .loading: + placeholder() + case let .result(data): + content(data: data) + case let .error(error): + ErrorView(error) + } } } + .leadingBar { + BarButton(.close) + } + .task { + await viewModel.fetchData() + } } - .leadingBar { - BarButton(.close) - } - .task { - await viewModel.fetchData() - } - } - @ViewBuilder - private func content(data: [CNContact]) -> some View { - ForEach(emails, id: \.self) { email in - if let contact = viewModel.getContactFromEmail(email: email, contacts: data) { - let emails = contact.emailAddresses - if !emails.isEmpty { - ForEach(emails, id: \.identifier) { email in - emailRow(email: email, contact: contact) + @ViewBuilder + private func content(data: [CNContact]) -> some View { + ForEach(emails, id: \.self) { email in + if let contact = viewModel.getContactFromEmail(email: email, contacts: data) { + let emails = contact.emailAddresses + if !emails.isEmpty { + ForEach(emails, id: \.identifier) { email in + emailRow(email: email, contact: contact) + } + } + } else { + Row(email) { + Avatar(firstName: email) } - } - } else { - Row(email) { - Avatar(firstName: email) } } } - } - @ViewBuilder - private func emailRow(email: CNLabeledValue, contact: CNContact) -> some View { - let email = email.value as String - #if os(iOS) - if let avatarThumbnailData = contact.thumbnailImageData, let avatarThumbnail = UIImage(data: avatarThumbnailData) { - Row(contact.givenName + " " + contact.familyName, subtitle: email) { - Avatar(firstName: contact.givenName, lastName: contact.familyName, avatar: Image(uiImage: avatarThumbnail)) + @ViewBuilder + private func emailRow(email: CNLabeledValue, contact: CNContact) -> some View { + let email = email.value as String + #if os(iOS) + if let avatarThumbnailData = contact.thumbnailImageData, let avatarThumbnail = UIImage(data: avatarThumbnailData) { + Row(contact.givenName + " " + contact.familyName, subtitle: email) { + Avatar(firstName: contact.givenName, lastName: contact.familyName, avatar: Image(uiImage: avatarThumbnail)) + } + } else { + Row(contact.givenName + " " + contact.familyName, subtitle: email) { + Avatar(firstName: contact.givenName, lastName: contact.familyName) + } } - } else { + #else Row(contact.givenName + " " + contact.familyName, subtitle: email) { Avatar(firstName: contact.givenName, lastName: contact.familyName) } - } - #else - Row(contact.givenName + " " + contact.familyName, subtitle: email) { - Avatar(firstName: contact.givenName, lastName: contact.familyName) - } - #endif - } + #endif + } - @ViewBuilder - private func placeholder() -> some View { - ForEach(emails, id: \.self) { email in - Row(email) { - Avatar(firstName: email) + @ViewBuilder + private func placeholder() -> some View { + ForEach(emails, id: \.self) { email in + Row(email) { + Avatar(firstName: email) + } } } } -} +#endif diff --git a/Sources/OversizeContactsKit/ContactsLists/ContactsListsViewModel.swift b/Sources/OversizeContactsKit/ContactsLists/ContactsListsViewModel.swift index bed0d93..8e7f414 100644 --- a/Sources/OversizeContactsKit/ContactsLists/ContactsListsViewModel.swift +++ b/Sources/OversizeContactsKit/ContactsLists/ContactsListsViewModel.swift @@ -3,56 +3,60 @@ // ContactsListsViewModel.swift // -import Contacts +#if canImport(Contacts) + import Contacts +#endif import Factory import OversizeContactsService import OversizeCore import OversizeModels import SwiftUI -@MainActor -public class ContactsListsViewModel: ObservableObject { - @Injected(\.contactsService) private var contactsService: ContactsService - @Published var state = ContactsPickerViewModelState.initial - @Published var searchText: String = .init() +#if !os(tvOS) + @MainActor + public class ContactsListsViewModel: ObservableObject { + @Injected(\.contactsService) private var contactsService: ContactsService + @Published var state = ContactsPickerViewModelState.initial + @Published var searchText: String = .init() - public init() {} + public init() {} - func fetchData() async { - state = .loading - let _ = await contactsService.requestAccess() - do { - let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactEmailAddressesKey, CNContactThumbnailImageDataKey] - let result = try await contactsService.fetchContacts(keysToFetch: keys as [CNKeyDescriptor]) - switch result { - case let .success(data): - log("✅ CNContact fetched") - state = .result(data) - case let .failure(error): - log("❌ CNContact not fetched (\(error.title))") - state = .error(error) + func fetchData() async { + state = .loading + let _ = await contactsService.requestAccess() + do { + let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactEmailAddressesKey, CNContactThumbnailImageDataKey] + let result = try await contactsService.fetchContacts(keysToFetch: keys as [CNKeyDescriptor]) + switch result { + case let .success(data): + log("✅ CNContact fetched") + state = .result(data) + case let .failure(error): + log("❌ CNContact not fetched (\(error.title))") + state = .error(error) + } + } catch { + state = .error(.custom(title: "Not contacts")) } - } catch { - state = .error(.custom(title: "Not contacts")) } - } - func getContactFromEmail(email: String, contacts: [CNContact]) -> CNContact? { - for contact in contacts where !contact.emailAddresses.isEmpty { - for emailAddress in contact.emailAddresses { - let emailAddressString = emailAddress.value as String - if emailAddressString == email { - return contact + func getContactFromEmail(email: String, contacts: [CNContact]) -> CNContact? { + for contact in contacts where !contact.emailAddresses.isEmpty { + for emailAddress in contact.emailAddresses { + let emailAddressString = emailAddress.value as String + if emailAddressString == email { + return contact + } } } + return nil } - return nil } -} -enum ContactsListsViewModelState { - case initial - case loading - case result([CNContact]) - case error(AppError) -} + enum ContactsListsViewModelState { + case initial + case loading + case result([CNContact]) + case error(AppError) + } +#endif diff --git a/Sources/OversizeContactsKit/ContactsPicker/EmailPickerView.swift b/Sources/OversizeContactsKit/ContactsPicker/EmailPickerView.swift index 3301f8b..274212f 100644 --- a/Sources/OversizeContactsKit/ContactsPicker/EmailPickerView.swift +++ b/Sources/OversizeContactsKit/ContactsPicker/EmailPickerView.swift @@ -3,168 +3,182 @@ // EmailPickerView.swift // -import Contacts +#if canImport(Contacts) + import Contacts +#endif import OversizeKit import OversizeLocalizable import OversizeUI import SwiftUI -public struct EmailPickerView: View { - @Environment(\.dismiss) private var dismiss - @StateObject private var viewModel: EmailPickerViewModel +#if !os(tvOS) + public struct EmailPickerView: View { + @Environment(\.dismiss) private var dismiss + @StateObject private var viewModel: EmailPickerViewModel - @Binding private var selection: [String] - @State private var selectedEmails: [String] = .init() + @Binding private var selection: [String] + @State private var selectedEmails: [String] = .init() - @FocusState private var isFocusSearth + @FocusState private var isFocusSearth - public init(selection: Binding<[String]>) { - _viewModel = StateObject(wrappedValue: EmailPickerViewModel()) - _selection = selection - } + public init(selection: Binding<[String]>) { + _viewModel = StateObject(wrappedValue: EmailPickerViewModel()) + _selection = selection + } - public var body: some View { - PageView("Add Invitees") { - Group { - switch viewModel.state { - case .initial, .loading: - placeholder() - case let .result(data): - content(data: data) - case let .error(error): - ErrorView(error) + public var body: some View { + PageView("Add Invitees") { + Group { + switch viewModel.state { + case .initial, .loading: + placeholder() + case let .result(data): + content(data: data) + case let .error(error): + ErrorView(error) + } } } + .leadingBar { + BarButton(.close) + } + .trailingBar { + BarButton(.accent("Done", action: { + onDoneAction() + })) + .disabled(selectedEmails.isEmpty && !viewModel.searchText.isEmail) + } + .topToolbar { + TextField("Email or name", text: $viewModel.searchText) + .textFieldStyle(DefaultPlaceholderTextFieldStyle()) + .focused($isFocusSearth) + #if os(iOS) + .keyboardType(.emailAddress) + #endif + } + .onAppear { + isFocusSearth = true + } + .task { + await viewModel.fetchData() + } } - .leadingBar { - BarButton(.close) - } - .trailingBar { - BarButton(.accent("Done", action: { - onDoneAction() - })) - .disabled(selectedEmails.isEmpty && !viewModel.searchText.isEmail) - } - .topToolbar { - TextField("Email or name", text: $viewModel.searchText) - .textFieldStyle(DefaultPlaceholderTextFieldStyle()) - .focused($isFocusSearth) - #if os(iOS) - .keyboardType(.emailAddress) - #endif - } - .onAppear { - isFocusSearth = true - } - .task { - await viewModel.fetchData() - } - } - @ViewBuilder - private func content(data: [CNContact]) -> some View { - LazyVStack(spacing: .zero) { - newEmailView() + @ViewBuilder + private func content(data: [CNContact]) -> some View { + LazyVStack(spacing: .zero) { + newEmailView() - newSelectedContactsRows(data: data) + newSelectedContactsRows(data: data) - contactsRows(data: data) + contactsRows(data: data) + } } - } - @ViewBuilder - private func newEmailView() -> some View { - if !viewModel.searchText.isEmpty { - Checkbox( - isOn: .constant(viewModel.searchText.isEmail), - label: { - Row(viewModel.searchText, subtitle: "New member") { - Avatar(firstName: viewModel.searchText) + @ViewBuilder + private func newEmailView() -> some View { + if !viewModel.searchText.isEmpty { + Checkbox( + isOn: .constant(viewModel.searchText.isEmail), + label: { + Row(viewModel.searchText, subtitle: "New member") { + Avatar(firstName: viewModel.searchText) + } } - } - ) - .padding(.bottom, .small) + ) + .padding(.bottom, .small) + } } - } - @ViewBuilder - private func newSelectedContactsRows(data: [CNContact]) -> some View { - if !viewModel.lastSelectedEmails.isEmpty { - HStack(spacing: .zero) { - Text("Latest") - Spacer() + @ViewBuilder + private func newSelectedContactsRows(data: [CNContact]) -> some View { + if !viewModel.lastSelectedEmails.isEmpty { + HStack(spacing: .zero) { + Text("Latest") + Spacer() + } + .title3() + .onSurfaceMediumEmphasisForegroundColor() + .padding(.vertical, .xxSmall) + .paddingContent(.horizontal) + + ForEach(viewModel.lastSelectedEmails, id: \.self) { email in + if let contact = viewModel.getContactFromEmail(email: email, contacts: data) { + let emails = contact.emailAddresses + if !emails.isEmpty { + ForEach(emails, id: \.identifier) { email in + emailRow(email: email, contact: contact) + } + } + } else { + let isSelected = selectedEmails.contains(email) + Checkbox( + isOn: Binding( + get: { isSelected }, + set: { _ in onContactClick(email: email) } + ), + label: { + Row(email) { + Avatar(firstName: email) + } + } + ) + } + } } - .title3() - .onSurfaceMediumEmphasisForegroundColor() - .padding(.vertical, .xxSmall) - .paddingContent(.horizontal) + } + + @ViewBuilder + private func contactsRows(data: [CNContact]) -> some View { + if !data.isEmpty { + HStack(spacing: .zero) { + Text("Contacts") + Spacer() + } + .title3() + .onSurfaceMediumEmphasisForegroundColor() + .padding(.vertical, .xxSmall) + .paddingContent(.horizontal) + .padding(.top, viewModel.lastSelectedEmails.isEmpty ? .zero : .small) - ForEach(viewModel.lastSelectedEmails, id: \.self) { email in - if let contact = viewModel.getContactFromEmail(email: email, contacts: data) { + ForEach(data, id: \.identifier) { contact in let emails = contact.emailAddresses if !emails.isEmpty { ForEach(emails, id: \.identifier) { email in emailRow(email: email, contact: contact) } } - } else { - let isSelected = selectedEmails.contains(email) - Checkbox( - isOn: Binding( - get: { isSelected }, - set: { _ in onContactClick(email: email) } - ), - label: { - Row(email) { - Avatar(firstName: email) - } - } - ) } } } - } - @ViewBuilder - private func contactsRows(data: [CNContact]) -> some View { - if !data.isEmpty { - HStack(spacing: .zero) { - Text("Contacts") - Spacer() - } - .title3() - .onSurfaceMediumEmphasisForegroundColor() - .padding(.vertical, .xxSmall) - .paddingContent(.horizontal) - .padding(.top, viewModel.lastSelectedEmails.isEmpty ? .zero : .small) - - ForEach(data, id: \.identifier) { contact in - let emails = contact.emailAddresses - if !emails.isEmpty { - ForEach(emails, id: \.identifier) { email in - emailRow(email: email, contact: contact) - } - } - } - } - } + @ViewBuilder + private func emailRow(email: CNLabeledValue, contact: CNContact) -> some View { + let email = email.value as String + let isSelected = selectedEmails.contains(email) + #if os(iOS) + if let avatarThumbnailData = contact.thumbnailImageData, let avatarThumbnail = UIImage(data: avatarThumbnailData) { + Checkbox(isOn: Binding( + get: { isSelected }, + set: { _ in onContactClick(email: email) } + ), label: { + Row(contact.givenName + " " + contact.familyName, subtitle: email) { + Avatar(firstName: contact.givenName, lastName: contact.familyName, avatar: Image(uiImage: avatarThumbnail)) + } - @ViewBuilder - private func emailRow(email: CNLabeledValue, contact: CNContact) -> some View { - let email = email.value as String - let isSelected = selectedEmails.contains(email) - #if os(iOS) - if let avatarThumbnailData = contact.thumbnailImageData, let avatarThumbnail = UIImage(data: avatarThumbnailData) { - Checkbox(isOn: Binding( - get: { isSelected }, - set: { _ in onContactClick(email: email) } - ), label: { - Row(contact.givenName + " " + contact.familyName, subtitle: email) { - Avatar(firstName: contact.givenName, lastName: contact.familyName, avatar: Image(uiImage: avatarThumbnail)) - } + }) + } else { + Checkbox(isOn: Binding( + get: { isSelected }, + set: { _ in onContactClick(email: email) } + ), label: { + Row(contact.givenName + " " + contact.familyName, subtitle: email) { + Avatar(firstName: contact.givenName, lastName: contact.familyName) + } - }) - } else { + }) + } + #else Checkbox(isOn: Binding( get: { isSelected }, set: { _ in onContactClick(email: email) } @@ -174,59 +188,48 @@ public struct EmailPickerView: View { } }) - } - #else - Checkbox(isOn: Binding( - get: { isSelected }, - set: { _ in onContactClick(email: email) } - ), label: { - Row(contact.givenName + " " + contact.familyName, subtitle: email) { - Avatar(firstName: contact.givenName, lastName: contact.familyName) - } + #endif + } - }) - #endif - } + private func onDoneAction() { + if viewModel.searchText.isEmail { + if !selection.contains(viewModel.searchText) { + selection.append(viewModel.searchText) + } - private func onDoneAction() { - if viewModel.searchText.isEmail { - if !selection.contains(viewModel.searchText) { - selection.append(viewModel.searchText) + if !viewModel.lastSelectedEmails.contains(viewModel.searchText) { + viewModel.lastSelectedEmails.append(viewModel.searchText) + } } - if !viewModel.lastSelectedEmails.contains(viewModel.searchText) { - viewModel.lastSelectedEmails.append(viewModel.searchText) - } - } + if !selectedEmails.isEmpty { + for email in selectedEmails where !selection.contains(email) { + selection.append(email) + } - if !selectedEmails.isEmpty { - for email in selectedEmails where !selection.contains(email) { - selection.append(email) + for email in selectedEmails where !viewModel.lastSelectedEmails.contains(email) { + viewModel.lastSelectedEmails.append(email) + } } - for email in selectedEmails where !viewModel.lastSelectedEmails.contains(email) { - viewModel.lastSelectedEmails.append(email) - } + dismiss() } - dismiss() - } - - private func onContactClick(email: String) { - let isSelected = selectedEmails.contains(email) - if isSelected { - selectedEmails.remove(email) - } else { - selectedEmails.append(email) + private func onContactClick(email: String) { + let isSelected = selectedEmails.contains(email) + if isSelected { + selectedEmails.remove(email) + } else { + selectedEmails.append(email) + } } - } - @ViewBuilder - private func placeholder() -> some View { - LoaderOverlayView() + @ViewBuilder + private func placeholder() -> some View { + LoaderOverlayView() + } } -} - +#endif // struct ContactsPickerView_Previews: PreviewProvider { // static var previews: some View { // EmailPickerView() diff --git a/Sources/OversizeContactsKit/ContactsPicker/EmailPickerViewModel.swift b/Sources/OversizeContactsKit/ContactsPicker/EmailPickerViewModel.swift index 8bbe16b..2c47623 100644 --- a/Sources/OversizeContactsKit/ContactsPicker/EmailPickerViewModel.swift +++ b/Sources/OversizeContactsKit/ContactsPicker/EmailPickerViewModel.swift @@ -3,61 +3,65 @@ // EmailPickerViewModel.swift // -import Contacts +#if canImport(Contacts) + import Contacts +#endif import Factory import OversizeContactsService import OversizeCore import OversizeModels import SwiftUI -@MainActor -class EmailPickerViewModel: ObservableObject { - @Injected(\.contactsService) private var contactsService: ContactsService - @Published var state = ContactsPickerViewModelState.initial - @Published var searchText: String = .init() +#if !os(tvOS) + @MainActor + class EmailPickerViewModel: ObservableObject { + @Injected(\.contactsService) private var contactsService: ContactsService + @Published var state = ContactsPickerViewModelState.initial + @Published var searchText: String = .init() - @AppStorage("AppState.LastSelectedEmails") var lastSelectedEmails: [String] = .init() + @AppStorage("AppState.LastSelectedEmails") var lastSelectedEmails: [String] = .init() - func fetchData() async { - state = .loading - let status = await contactsService.requestAccess() - switch status { - case .success: - do { - let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactEmailAddressesKey, CNContactThumbnailImageDataKey] - let result = try await contactsService.fetchContacts(keysToFetch: keys as [CNKeyDescriptor]) - switch result { - case let .success(data): - log("✅ CNContact fetched") - state = .result(data) - case let .failure(error): - log("❌ CNContact not fetched (\(error.title))") - state = .error(error) + func fetchData() async { + state = .loading + let status = await contactsService.requestAccess() + switch status { + case .success: + do { + let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactEmailAddressesKey, CNContactThumbnailImageDataKey] + let result = try await contactsService.fetchContacts(keysToFetch: keys as [CNKeyDescriptor]) + switch result { + case let .success(data): + log("✅ CNContact fetched") + state = .result(data) + case let .failure(error): + log("❌ CNContact not fetched (\(error.title))") + state = .error(error) + } + } catch { + state = .error(.contacts(type: .unknown)) } - } catch { - state = .error(.contacts(type: .unknown)) + case let .failure(error): + state = .error(error) } - case let .failure(error): - state = .error(error) } - } - func getContactFromEmail(email: String, contacts: [CNContact]) -> CNContact? { - for contact in contacts where !contact.emailAddresses.isEmpty { - for emailAddress in contact.emailAddresses { - let emailAddressString = emailAddress.value as String - if emailAddressString == email { - return contact + func getContactFromEmail(email: String, contacts: [CNContact]) -> CNContact? { + for contact in contacts where !contact.emailAddresses.isEmpty { + for emailAddress in contact.emailAddresses { + let emailAddressString = emailAddress.value as String + if emailAddressString == email { + return contact + } } } + return nil } - return nil } -} -enum ContactsPickerViewModelState { - case initial - case loading - case result([CNContact]) - case error(AppError) -} + enum ContactsPickerViewModelState { + case initial + case loading + case result([CNContact]) + case error(AppError) + } +#endif diff --git a/Sources/OversizeLocationKit/MapCoordinateView/MapCoordinateView.swift b/Sources/OversizeLocationKit/MapCoordinateView/MapCoordinateView.swift index 93ed613..4aaecb7 100644 --- a/Sources/OversizeLocationKit/MapCoordinateView/MapCoordinateView.swift +++ b/Sources/OversizeLocationKit/MapCoordinateView/MapCoordinateView.swift @@ -138,11 +138,13 @@ public struct MapCoordinateView: View { } func onTapAppleMaps() { - let placemark = MKPlacemark(coordinate: viewModel.location, addressDictionary: nil) - let mapItem = MKMapItem(placemark: placemark) - mapItem.name = viewModel.annotation - mapItem.openInMaps() - viewModel.isShowRoutePickerSheet.toggle() + #if !os(tvOS) + let placemark = MKPlacemark(coordinate: viewModel.location, addressDictionary: nil) + let mapItem = MKMapItem(placemark: placemark) + mapItem.name = viewModel.annotation + mapItem.openInMaps() + viewModel.isShowRoutePickerSheet.toggle() + #endif } func onTapGoogleMaps() { diff --git a/Sources/OversizeNotificationKit/LocalNotificationSetScreenViewModel.swift b/Sources/OversizeNotificationKit/LocalNotificationSetScreenViewModel.swift index be6e46c..66f9e4e 100644 --- a/Sources/OversizeNotificationKit/LocalNotificationSetScreenViewModel.swift +++ b/Sources/OversizeNotificationKit/LocalNotificationSetScreenViewModel.swift @@ -9,68 +9,70 @@ import OversizeModels import OversizeNotificationService import SwiftUI -@MainActor -class LocalNotificationSetScreenViewModel: ObservableObject { - @Injected(\.localNotificationService) var localNotificationService: LocalNotificationServiceProtocol - @Published var state = State.initial +#if !os(tvOS) + @MainActor + class LocalNotificationSetScreenViewModel: ObservableObject { + @Injected(\.localNotificationService) var localNotificationService: LocalNotificationServiceProtocol + @Published var state = State.initial - public let id: UUID - private let date: Date - private let title: String - private let body: String - private let userInfo: [AnyHashable: Any]? + public let id: UUID + private let date: Date + private let title: String + private let body: String + private let userInfo: [AnyHashable: Any]? - init( - id: UUID, - date: Date, - title: String, - body: String, - userInfo: [AnyHashable: Any]? = nil - ) { - self.id = id - self.date = date - self.title = title - self.body = body - self.userInfo = userInfo - } + init( + id: UUID, + date: Date, + title: String, + body: String, + userInfo: [AnyHashable: Any]? = nil + ) { + self.id = id + self.date = date + self.title = title + self.body = body + self.userInfo = userInfo + } - func setNotification(timeBefore: LocalNotificationTime) async { - let notificationTime = date.addingTimeInterval(timeBefore.timeInterval) - let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: notificationTime) - await localNotificationService.schedule(localNotification: .init( - id: id, - title: title, - body: body, - dateComponents: dateComponents, - repeats: false, - userInfo: userInfo - )) - } + func setNotification(timeBefore: LocalNotificationTime) async { + let notificationTime = date.addingTimeInterval(timeBefore.timeInterval) + let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: notificationTime) + await localNotificationService.schedule(localNotification: .init( + id: id, + title: title, + body: body, + dateComponents: dateComponents, + repeats: false, + userInfo: userInfo + )) + } - func fetchPandingNotification() async -> Bool { - let ids = await localNotificationService.fetchPendingIds() - return ids.contains(id.uuidString) - } + func fetchPandingNotification() async -> Bool { + let ids = await localNotificationService.fetchPendingIds() + return ids.contains(id.uuidString) + } - func deleteNotification() { - localNotificationService.removeRequest(withIdentifier: id.uuidString) - } + func deleteNotification() { + localNotificationService.removeRequest(withIdentifier: id.uuidString) + } - func requestAccsess() async { - let result = await localNotificationService.requestAccess() - switch result { - case .success: - state = .result - case let .failure(error): - state = .error(error) + func requestAccsess() async { + let result = await localNotificationService.requestAccess() + switch result { + case .success: + state = .result + case let .failure(error): + state = .error(error) + } } } -} -extension LocalNotificationSetScreenViewModel { - enum State { - case initial - case result - case error(AppError) + extension LocalNotificationSetScreenViewModel { + enum State { + case initial + case result + case error(AppError) + } } -} +#endif diff --git a/Sources/OversizeNotificationKit/LocalNotificationView.swift b/Sources/OversizeNotificationKit/LocalNotificationView.swift index 87cbe51..e574636 100644 --- a/Sources/OversizeNotificationKit/LocalNotificationView.swift +++ b/Sources/OversizeNotificationKit/LocalNotificationView.swift @@ -9,106 +9,108 @@ import OversizeUI import SwiftUI import UserNotifications -public struct LocalNotificationView: View { - @Environment(\.dismiss) var dismiss - @Binding private var selection: LocalNotificationTime - @State private var isPendingNotification: Bool = false - @StateObject var viewModel: LocalNotificationSetScreenViewModel - private let saveAction: ((UUID?) -> Void)? +#if !os(tvOS) + public struct LocalNotificationView: View { + @Environment(\.dismiss) var dismiss + @Binding private var selection: LocalNotificationTime + @State private var isPendingNotification: Bool = false + @StateObject var viewModel: LocalNotificationSetScreenViewModel + private let saveAction: ((UUID?) -> Void)? - public init( - _ selection: Binding, - id: UUID, - title: String, - body: String, - date: Date, - userInfo: [AnyHashable: Any]? = nil, - saveAction: ((UUID?) -> Void)? = nil - ) { - _viewModel = StateObject(wrappedValue: LocalNotificationSetScreenViewModel( - id: id, - date: date, - title: title, - body: body, - userInfo: userInfo - )) - _selection = selection - self.saveAction = saveAction - } + public init( + _ selection: Binding, + id: UUID, + title: String, + body: String, + date: Date, + userInfo: [AnyHashable: Any]? = nil, + saveAction: ((UUID?) -> Void)? = nil + ) { + _viewModel = StateObject(wrappedValue: LocalNotificationSetScreenViewModel( + id: id, + date: date, + title: title, + body: body, + userInfo: userInfo + )) + _selection = selection + self.saveAction = saveAction + } - public var body: some View { - switch viewModel.state { - case .initial: - contnent - .task { - await viewModel.requestAccsess() - } - case .result: - contnent - .task { - let pendingStatus = await viewModel.fetchPandingNotification() - if pendingStatus { - isPendingNotification = true + public var body: some View { + switch viewModel.state { + case .initial: + contnent + .task { + await viewModel.requestAccsess() } + case .result: + contnent + .task { + let pendingStatus = await viewModel.fetchPandingNotification() + if pendingStatus { + isPendingNotification = true + } + } + case let .error(error): + PageView("Notification") { + ErrorView(error) + } + .leadingBar { + BarButton(.close) } - case let .error(error): - PageView("Notification") { - ErrorView(error) - } - .leadingBar { - BarButton(.close) } } - } - public var contnent: some View { - // let notificationDate = viewModel.date.addingTimeInterval(selection.timeInterval) - PageView("Notification") { - VStack(spacing: .zero) { - SectionView { - LazyVStack(spacing: .zero) { - ForEach(LocalNotificationTime.allCases) { notificationTime in + public var contnent: some View { + // let notificationDate = viewModel.date.addingTimeInterval(selection.timeInterval) + PageView("Notification") { + VStack(spacing: .zero) { + SectionView { + LazyVStack(spacing: .zero) { + ForEach(LocalNotificationTime.allCases) { notificationTime in // let notificationDate = viewModel.date.addingTimeInterval(notificationTime.timeInterval) // if notificationDate viewModel.date { - Radio(notificationTime.title, isOn: selection.id == notificationTime.id) { - selection = notificationTime + Radio(notificationTime.title, isOn: selection.id == notificationTime.id) { + selection = notificationTime + } + // } } - // } } } - } - .surfaceContentRowMargins() - if isPendingNotification { - SectionView { - VStack(spacing: .zero) { - Row("Delete notification") { - viewModel.deleteNotification() - saveAction?(nil) - isPendingNotification = false - dismiss() - } trailing: { - IconDeprecated(.trash) - .iconColor(Color.error) + .surfaceContentRowMargins() + if isPendingNotification { + SectionView { + VStack(spacing: .zero) { + Row("Delete notification") { + viewModel.deleteNotification() + saveAction?(nil) + isPendingNotification = false + dismiss() + } trailing: { + IconDeprecated(.trash) + .iconColor(Color.error) + } } } + .surfaceContentRowMargins() } - .surfaceContentRowMargins() } } - } - .backgroundSecondary() - .leadingBar { - BarButton(.close) - } - .trailingBar { - BarButton(.accent("Done", action: { - Task { - await viewModel.setNotification(timeBefore: selection) - saveAction?(viewModel.id) - isPendingNotification = true - dismiss() - } - })) + .backgroundSecondary() + .leadingBar { + BarButton(.close) + } + .trailingBar { + BarButton(.accent("Done", action: { + Task { + await viewModel.setNotification(timeBefore: selection) + saveAction?(viewModel.id) + isPendingNotification = true + dismiss() + } + })) + } } } -} +#endif diff --git a/Sources/OversizeNotificationKit/Model/LocalNotificationAlertsTimes.swift b/Sources/OversizeNotificationKit/Model/LocalNotificationAlertsTimes.swift index 2c45852..79909ad 100644 --- a/Sources/OversizeNotificationKit/Model/LocalNotificationAlertsTimes.swift +++ b/Sources/OversizeNotificationKit/Model/LocalNotificationAlertsTimes.swift @@ -3,7 +3,9 @@ // LocalNotificationAlertsTimes.swift // -import EventKit +#if canImport(EventKit) + import EventKit +#endif import Foundation public enum LocalNotificationTime: CaseIterable, Equatable, Identifiable { diff --git a/Sources/OversizePhotoKit/PhotoOptionsView.swift b/Sources/OversizePhotoKit/PhotoOptionsView.swift index d36ba2e..904582c 100644 --- a/Sources/OversizePhotoKit/PhotoOptionsView.swift +++ b/Sources/OversizePhotoKit/PhotoOptionsView.swift @@ -63,20 +63,21 @@ public struct PhotoOptionsView: View where A: View { VStack(spacing: .medium) { SectionView { VStack { - if #available(iOS 16.0, *) { - ShareLink( - item: photo, - preview: SharePreview( - "Photo", - image: photo.image - ) - ) { - Row("Share") { - Image.Base.upload + #if !os(tvOS) + if #available(iOS 16.0, *) { + ShareLink( + item: photo, + preview: SharePreview( + "Photo", + image: photo.image + ) + ) { + Row("Share") { + Image.Base.upload + } } } - } - + #endif actions } .buttonStyle(.row)