From 646b489de6e6de016fedcf046ad988794922e179 Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Fri, 27 Sep 2024 00:19:12 -0500 Subject: [PATCH 01/18] Add asset for dark mode icon --- .../AppIcon.appiconset/Contents.json | 149 ++++-------------- .../AppIcon.appiconset/Icon 1.png | Bin 0 -> 77601 bytes .../AppIcon.appiconset/icon_20pt.png | Bin 436 -> 0 bytes .../AppIcon.appiconset/icon_20pt@2x.png | Bin 1002 -> 0 bytes .../AppIcon.appiconset/icon_20pt@3x.png | Bin 1587 -> 0 bytes .../AppIcon.appiconset/icon_29pt.png | Bin 683 -> 0 bytes .../AppIcon.appiconset/icon_29pt@2x.png | Bin 1539 -> 0 bytes .../AppIcon.appiconset/icon_29pt@3x.png | Bin 2484 -> 0 bytes .../AppIcon.appiconset/icon_40pt.png | Bin 1002 -> 0 bytes .../AppIcon.appiconset/icon_40pt@2x.png | Bin 2279 -> 0 bytes .../AppIcon.appiconset/icon_40pt@3x.png | Bin 3596 -> 0 bytes .../AppIcon.appiconset/icon_60pt@2x.png | Bin 3596 -> 0 bytes .../AppIcon.appiconset/icon_60pt@3x.png | Bin 5786 -> 0 bytes .../AppIcon.appiconset/icon_76pt.png | Bin 2108 -> 0 bytes .../AppIcon.appiconset/icon_76pt@2x.png | Bin 4837 -> 0 bytes .../AppIcon.appiconset/icon_83.5@2x.png | Bin 5376 -> 0 bytes .../AppIcon.beta.appiconset/Contents.json | 135 ++++------------ .../AppIcon.beta.appiconset/Icon 1.png | Bin 0 -> 89603 bytes .../AppIcon.beta.appiconset/icon_20pt.png | Bin 500 -> 0 bytes .../AppIcon.beta.appiconset/icon_20pt@2x.png | Bin 1160 -> 0 bytes .../AppIcon.beta.appiconset/icon_20pt@3x.png | Bin 1858 -> 0 bytes .../AppIcon.beta.appiconset/icon_29pt.png | Bin 785 -> 0 bytes .../AppIcon.beta.appiconset/icon_29pt@2x.png | Bin 1784 -> 0 bytes .../AppIcon.beta.appiconset/icon_29pt@3x.png | Bin 2874 -> 0 bytes .../AppIcon.beta.appiconset/icon_40pt.png | Bin 1160 -> 0 bytes .../AppIcon.beta.appiconset/icon_40pt@2x.png | Bin 2621 -> 0 bytes .../AppIcon.beta.appiconset/icon_40pt@3x.png | Bin 4117 -> 0 bytes .../AppIcon.beta.appiconset/icon_60pt@2x.png | Bin 4117 -> 0 bytes .../AppIcon.beta.appiconset/icon_60pt@3x.png | Bin 6568 -> 0 bytes .../AppIcon.beta.appiconset/icon_76pt.png | Bin 2419 -> 0 bytes .../AppIcon.beta.appiconset/icon_76pt@2x.png | Bin 5444 -> 0 bytes .../AppIcon.beta.appiconset/icon_83.5@2x.png | Bin 6040 -> 0 bytes .../AppIcon.debug.appiconset/Contents.json | 135 ++++------------ .../AppIcon.debug.appiconset/Icon 1.png | Bin 0 -> 88839 bytes .../AppIcon.debug.appiconset/icon_20pt.png | Bin 491 -> 0 bytes .../AppIcon.debug.appiconset/icon_20pt@2x.png | Bin 1137 -> 0 bytes .../AppIcon.debug.appiconset/icon_20pt@3x.png | Bin 1824 -> 0 bytes .../AppIcon.debug.appiconset/icon_29pt.png | Bin 766 -> 0 bytes .../AppIcon.debug.appiconset/icon_29pt@2x.png | Bin 1749 -> 0 bytes .../AppIcon.debug.appiconset/icon_29pt@3x.png | Bin 2832 -> 0 bytes .../AppIcon.debug.appiconset/icon_40pt.png | Bin 1137 -> 0 bytes .../AppIcon.debug.appiconset/icon_40pt@2x.png | Bin 2597 -> 0 bytes .../AppIcon.debug.appiconset/icon_40pt@3x.png | Bin 4066 -> 0 bytes .../AppIcon.debug.appiconset/icon_60pt@2x.png | Bin 4066 -> 0 bytes .../AppIcon.debug.appiconset/icon_60pt@3x.png | Bin 6516 -> 0 bytes .../AppIcon.debug.appiconset/icon_76pt.png | Bin 2397 -> 0 bytes .../AppIcon.debug.appiconset/icon_76pt@2x.png | Bin 5414 -> 0 bytes .../AppIcon.debug.appiconset/icon_83.5@2x.png | Bin 5977 -> 0 bytes 48 files changed, 85 insertions(+), 334 deletions(-) create mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/Icon 1.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_20pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_29pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_40pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_76pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png create mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/Icon 1.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_20pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_20pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_20pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_29pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_29pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_29pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_40pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_40pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_40pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_60pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_60pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_76pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_76pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_83.5@2x.png create mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/Icon 1.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_20pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_20pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_20pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_29pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_29pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_29pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_40pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_40pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_40pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_60pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_60pt@3x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_76pt.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_76pt@2x.png delete mode 100644 BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_83.5@2x.png diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json b/BookPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json index 6412c2a0f..4143c2759 100644 --- a/BookPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/BookPlayer/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,128 +1,37 @@ { "images" : [ { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "icon_83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", "filename" : "Icon.png", - "scale" : "1x" - }, - { - "size" : "60x60", - "idiom" : "car", - "filename" : "icon_60pt@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "car", - "filename" : "icon_60pt@3x.png", - "scale" : "3x" + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "Icon 1.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/Icon 1.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/Icon 1.png new file mode 100644 index 0000000000000000000000000000000000000000..69bd042ed63bb4d908eb3ce0ac01311b79669d4e GIT binary patch literal 77601 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 KelF{r5}E+6@P>o{ literal 0 HcmV?d00001 diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_20pt.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_20pt.png deleted file mode 100644 index c9397c2a146571fe43365e35bab8024fee162e82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 436 zcmV;l0ZaagP)%H8x|C3Az}mo7?IAEFdx0r zYZgCzvX<<^$Bm3z%uHKttlDGarm&zu3(-De0st_;66W0}8dT4;1-r0uL!%bC3q}Bd z0hTatJy4;#r_9-fjQ!F60mJbL)6Oov#wM+3F#-S#u!MR2o&wb^Y0mb`Y+>0R9X&~* zu<9H3BcmoNDmEZu1OOOdN%P&8IdRS|coZC;FZkABuB_Uqs@{Z%5ddI-)iu}FZdF!p z$T6#P*&(50#U-oCE_?G{;RCa^>q0I5zyM2_cOI$gzbe4;LxLoHhs4gdGcA1{3knq> zK|J@KXy5US3>Yd%n_HQ?6@2|rpoRDyPhf!Me;7m}v$KBhWdB`UM+=cC8kUTK0sj2? eN2K7ul_UV{N62;|z0bJ-0000a?or-seuM z`dx?J+0$*0M~Mvapaqu~e7JSN_~k=mY#9P%hzAth+|u(n{gvMQtFz0Ne(%}!GkO-Q z{%15jL!v>91tWGK2?RS_Znl=Ee-5A0upBw9-MBLE$gYZOr*&{k^WNKSK^K!IoeUvB zh8T-@fe27Nxbl75h3bFzO${d>yt$-!{~Xbk!-7CwN7{@DcYzmJuWGD@wAW zJmw&L6pMI)2n^@S+16F;85W6OJA= z`axCI*Y@^4Xyq&j~d+PaD@l^&UliNJY#0Y+<95AUezJ?1z*2mU9vRyaq`R4 zXY``P5*}=e8SFpfh5Nk03p~NL;0enYJZEm^ix>ZNUT^l$->8f*(Z;{%%bU#IiujT+5&4nkfh zAU+`Q#3m4C1Jwy++qN?9asMX}CbglQGGl%uF4p`TijM?Xm9Nt^P2Es@7Qw0n^TihF zs?+A!g}}_&87#320U+@f0*@_?B3*ml8dCa<8~cFzW_r@&^~-Z_UNBH?v2Z|>PKFSK zls-U&2394w!c*)uo_P3bRdBJlY;MNh%_WylXbUpl_$Ct$Xwu0Lg1}-AI}lI+!6sbZ z9y_buvL^q;zDg;ZHRWGi!7m0)I%O0YVk`-lx4yro=Kl+NqvdyZk6jA-8)pqKtbd~E z8A5;zF&2!f1-<%TS>F5G7fs(jH^-JCK!$kG{&#XZT)jPxc$CPT{|#0qkM@s8Egm2M Y0AXDv$r?|=e*gdg07*qoM6N<$f>Uhe6951J diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png deleted file mode 100644 index c1fc9125d7da77af9e50646cabc5464be11a111a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1587 zcmV-32F&@1P)(QKeW^rd(F1WL&CwaJ7+#!qUy<;qCZ)pwv}s zv`I^&O--axPo-5-ret2Mq@d2)>Gyb?(o|@()#vtgna)&ZvUZuz(Bt%Tmd;aTu*=}{ za+J);-}7*i%u-^n#@_R9kIGSDuXcC3-{0?WakflNq{Q6vZH~!NU#@_Gzxnz6lat6@ zUaj@@`EYT!Y>dZHU#*Lb#QgmIp`y?7^7vq3uE5&yY>UWHUapsz%3NKoTU@Nc!QaWr zbbew z$H(HTtJJ>O@M?<2P+hG}PNh&$rkI$^&(P<+*zjqI#!p?WXlb&9guvtD@M?<3VPda| ziNoIB?vIeh?CkZTqR_tC@lal^+1l)EjL2qZv8AQav9j27b-9+8%BZQ+!P@cH*XzUF z@lao`z`);CR;k9_@={^0$lmkH;PcDj^U&kcG z>-XjG`EF&ehJ3rVt<{c|$ANjek%qy+y4&#a_?)56pry~z)ad&A{m{zf^Yr<V!cIY~r8RCodHmII7DNf^c7*V>-5ZQHhO2WLAx+ZUW| z+h+7P*0ybX>+0*B{W4XvoxK>lzhqu&>b=(%<|_-3<01{$A*A8Vl5^b*SY+tQxyoTe zO917q1%tIbrKf>Jh*ZeJnt7EqE7NqHcW_=#jVOuH(v$LwjHcHbC&3Zg)vdX)V9?>+tIz!AV00%2ZFLhlt z4WLw+Sw5r>+9${odUyl=#fiMi^`r;Yt7V;)i11kWe;-RfADDqCwHay70(Um!X>CN2 zs0_25h@_uo08CUMC@~+><&3f;;v)v%$k}Ta z5q92XSFO9nM5LUNBEnwb2m0T>;r@2SD*wR}ibNcgcoUl3AUMo)|FFuJrI(L-`9)}s zK4xVYn(k%RsWR=82%tw0u?C$!xaOI^8WF3!CL%b@zk48rM897^Ny7-6Yu+$QV*G;>DN!e&+LL#9H&=GRYG0!tHm0IoCP6*>n%L%8ocEV20JhH$pSGmG^}hBNDcs zB%{`oq+sW(MtL7%BIXlil0~mYD2Jd8iP#SVVwqwYM+}iMWtFWpUxOGT<7yVN%C0Q- zEyVDah&$V6-^_9=AUyGe47DKc_4J!C?43Gc-002ovPDHLkV1n!}h>-vQ diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_29pt.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_29pt.png deleted file mode 100644 index 1968b0c7f6d97259c68a0f7412ba74f99e5e94ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 683 zcmV;c0#yBpP)jBEZ|0bc@9rP_md~cPE`now-Thl_ z9cpz{@|`WKBm7#s+m;?49>Cxdw~-)6YwJ)0G9<1SQ<#N;;@v#H32WNKpMp(;lu4D8 zW{HqsnwW69w0NeWR&iQ<-`VLEE^!+Pa*Z&2MD$1BG? z-le6(7l3%Zy<6?=>+|x*(Sji`rZ5Ww)qBP~-dc`VP>y-L8yhDqucA^xbWCqy(F9sB z1jZC*VfgyT3#qATRZi|0{qcVF>#M0%l9)JPU{L=4^<}&;eEsJ^NI1hkp#9^YhcEm5 zYG{^x&F6P|`|_K=ZOrn4=_-?8%Niq#(sLc&*UVt%niya zizn`G?{SISNT~Y^28#Fg{( zbGfErZhCr`IWNMym*)0a021VA!GOeh@kQs`Jx;LQ?K5hN94(k%a~}WqJ^|oJ^^EQn R_L%?x002ovPDHLkV1k^`PaFUM diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png deleted file mode 100644 index 74bdad97ba344b73f2eab6245cf32b3895389be1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1539 zcmV+e2K@PnP)3p1L+oS5Hon3`%9lvOseiw4?gMk2JB2sdmoCxRg2 z2qhW-4cx2Gdk$2*l(ld}^^EueDlDO3?r%k5Q7O|V*}|sUqozAV_M)him5F)#w^pUw zuk>^e2on}qWh1+25S>U6BF6+P42AQejWuc_02;VWkGfRxyfu|L${IV>F>=&-QKQG4 zA3x4Ad4hHNWLx-Dd-TGLU7IRiJnNuXV3m#RqJcJ=r4SRrz|FdBz@3>;Xuut7`FvbVR8Jz*L;y5!(=WBC zV%3)#IhwrBElm7u)kFX^a8oY$aQBryH~Qv(6eTP?B|YN?f6d#lQk@Bsp#W&$Cb{29 z<=&EKs_FEYJadRSbJJhE=)`2}wra5@Epn+>`Qg90mM|WDZ0e8}52SC(cD@*$NhS2)q=H}im zDY?(WjvY0xUUjKjtW;-$WGDa{xRypA?ykVNdHHufC|7Z3h9z@cckHa?v)kQ0z~?v+ z?k)uv01e#pjce{%F#vy@|{Iuj&A0r)bw z91>mJ=;+*m0S^n=*|$>DuB%7)N5uW}uM)n3EEE*nwL7i^#LYM2ey@f`8-ik*1HF zgo}N+0BGPkUGIFjewR40`MQ@lkx{7+f{Lt-;MhO>*wQQ zqIwdcCIX;=Tj@U*DKm~m>?Ryz$6BIe^P*#OSuknCMD-*>O$0y#xACEI=(IMdq0`)m zq?L&Usn$#VeM1xrtgjN|B>EIXWWv^t*c8JGgcJdl}`Xz zV3m#RqJg&eMta48MtT5f;CA+VPSpN8Fy&*k=j^2q4onwDCI6L>cVKIk9PyeAcWI*; z$p;6fL=YqfrbGjvJv}!WN5?G6*u1htjCHBg2O1vSc^AlsT{MVJBnXk4jH5qy*k9N5 zRG98LR9{;8psxB6!LlsJnqR-{GIyYXHdTcQRu~FrBEHzO36ICy=z4bj<{K9L9;Kw5 zyV%*$AB+iYH2XbD!4O-_S@>EHs#@Omh{(LO8{C8iFQgfX&|>oK9s}OG_WJszm!I|+ p5Fzr=L)H*(2seZq!u=Uu{{Rsd+QwvX7`y-g002ovPDHLkV1h>C?`r@6 diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png deleted file mode 100644 index 891361617960d15e75d9b5be857382599d4c472d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2484 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 Y0AXDv$r?|=e*gdg07*qoM6N<$f>Uhe6951J diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png deleted file mode 100644 index 0bd308c33d0f88537b7adac17b5ad19a0a954595..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2279 zcmYLLdpHx^A0N34+dCw=HAHUZE=njYOeR!FqRrfLTe*`fBAm7`Mc6G2f7iE7u2VKFbQ?eQE3=heMKk?Q`52PGneuu&q zm$L(KZ|h1`S1m+@7^eUukU>H7$00zVouJZ}(?rHjca6#g=D*ENGd1&GAFcS?xPTjI zsfAf->&}gW?C<5IXT5#7G8fWxEREh|{2X`lv)P|iR@LW#Ix16|Zk7r_+oUs=rt5;8 zXjw}uaocZRAu&FRhaU-h=2@jyNkE}}_qx#zFqwD7@jyfVP?*gok7Vpx3BV-OwUHRQ zVmCHGQ!V+l6yG{tXlh(*<57nP9Q$JDW0k=WqnIm{1~l*J&P+GP8eE|up1RDvMctmL z$ZAnu?-*~+tahB+E-Pw$9_=r#q=g{z0y%{Wy`thlmWC_BN!BlLrjZ51m{a8oZZ5>2 z*bBGd(Wah*EiXEu2Wj*%Z;eX%E|H@LHy6jn!j@tE6u;c$E${G~r!Up-;IZ;bD!Op_ zjF2;Qg54uYk$6y>oB)z)uIM1*{{gd`qY+QPp%|x7YmISu<_7Qbx=`(xwZLB$`55SoNBJ<;k^^oV9eoJGv1^+!U9W& z=9itnK2EgXJ3@aTgr%lPq#E($>&$ukeUgjX$by4v1WX_767-2h+G+7-lV|T*6h3^` znThNjvj8)1JVa$ge0uWs<0Snz22DUn#^wzanHp`?St*9OvqC6#_$EtZ5{|?0(w(&^ zFq1Kb6{U2!pB&W^JFJP)TM^~}M7klESzNgYL%l3->Cp%Md4{w>_jOSqLMCF(Q8DbQ z=%oK%GQ7xv!=puvVurm);KZH5Z(#DPsEN4rw;ta0aLONWw^&3Zu!g==^6rLfkoR_T zv=d~vviI4{ZdTQ<;Vngm5z(>qteA`kXIV_2RjRN<&3){JkKm9T|82&i1 zDP}w^EzONwcm(nHUg3{~hxx$a5Ksz+?1{T7&NqF7jP}KNdY+;>Py!cBuxG&v3Z+nJ zCrU%?@M2&t5-qJaHlV59G#hr?$|$(yw6xm`rLy8;Y3IIL1+U)a?JZI>iIju$0`7fs ziP_$ERo$l52E#l4$#|h}&CeeS30>V> z0Cj;BEH2{x@8Cu`ECgAD$lcpLn6E?9h6%{lj;TY&5ZMu*RRf!Rw$gE>-&grZN$8Dz z(p7AoPnRq_*}FLU7_+Pt-h?~(^1y+ANF<_Q>$`UtG&*-gODqb!Zu2)XZlI(Uk7V|F zNE3IYXw}sV)UK-Cp4vIk;zka5-5NZqh?~kgKDVJ1+*k7RN5JQfd(UR2X>5k$o<2^Lraw&E^g)F5%H{JwGp-TNDqm`ofFz0T;3Cq=zQI|9c;&@5UZfS zYOpR-6PPpoWah6CoH$fsmz9&f1ANi%IMVChtF z1`vM8`{2)Yqkg`#uOrhXEgBf3l#HY%<4OLcSw{q7s^tCc*Fg{=^vgt?0f6s&AmG(8 zEizY;Yn8K$hP(U(0Bg3$_pZpE60@QXC9~9_?&1z#;KYJ8_37yfE}+pKrr4IXyL5lD(SpHcL6WuF~RY>y47NOtkEqch9JNOt)zg8WW+ zhBiF4{%u}mVkE6xF;)6lDq}0zWyD6(R&9S*wn<9cY6C3x=#`t>WPjg?}F>=o5k#E zMDfA%ir0m%?-SZ)KW@ksu%Rh(^UBpmC7%;Xx>%VBIUS1}#7x8zqIY5a#1s~4Iq2ry z@%z3N+LvJfag2&y8I|yedzqkvUD+Xl*iP7gW%GtJ?u+9`gR9zwY?JHH$Oz(#?p#Dx z+QuAq=i0cRadr69F2xB@__=4(xn1fVH4)Z7;1hq!LLMu{MJ0^o7^xlFGLoIly|s=D zIU^Gv&khM9>Cr<~ncVJ83v<&3zj^>K^Q%+mkMt|j~jTA^iG diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png deleted file mode 100644 index 991179559560bcb58ca996f58529c4072387f0b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3596 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 diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_76pt.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_76pt.png deleted file mode 100644 index da330dfbc1d7ec4bba6ed79948d125240848129e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2108 zcmY+Gdpr~BAIHT`7Lwr*xirf)nM*FYZ|3eeEw)m~m}@wkgmR0inaCw^+Ux9u zI3dVx{{&E2usZRcB?<`vMVt{Z&-h)7w|H>}Xv&n$&sO>q7~;T7Oi)lzu{Jh{m|LuX zBhQW-KCJL0k<01xqybRr=-Xn|py1%IU8*F%>CK!JzG|nNQvg(EB>gD(H>aP8+G}0% z$py7l7HlW7cBLMiCYwh64#LhoCDzxtgqjW(n!f8kl_5(5Mc0AZM$~Os!qVirnKt>B zTO%4he9Xea;;dI;^YMCIL##0IRDuZkape3*g4#HRjiLlHOg7DMiLI^EA)(LrGMOIF z0*hZt!vJ2fm{d@#`&r?5B|{cQ#Jw?g9vkfjU+i6^7yVuU1TiCR4kWYn?>s-MAx;A! z+&9z6G4IoGK7*bQ}EY&$w)pgf!;KL$9s8ef3Wn!`W*j(dcfY)xd%L2z|O|@bc5-*qjbHqXvf*IUq>h zN{fBlVG(_UHX}o-+LxrxSeTfzJc&;=a0~uv;)E-@jsR^yp1pT7PH#j(Z60wdufLI zkQbaJ!26NEf)hwGX=8*|6}n+eM81-HWJOZ4sTq~?mWWkUHpy;)d&gSlO+f&VIyLNO zeKd?6;!+c?K-S4SsuGq#yWTIA210?zm?*bl^Q}s|2NJ${ACEcp2Rix#do${QUJO&6 z5M{Tpq9eFM%0)@(XnNj$xc(g-xHaorO=X+SZItMr_cXypUu>oAfDQtMG6zAhbANbW z3s-p5kIVhv0S$KPlQN?XBJEmZ=l`?)=#^f`VrE$W5fL^2Ed10HNO1gnkg`uel=Tc5 zVvz1fi7>IJ_MuBE+l=avqK3NTelvFXYeZtu@yPJRyUI=X6f&`pS9~=MvxUQ~ZuqA-9;L~P~ z6j9K&kY-lFf=o`SJ9Xupi+UprUR|~5=pe;xkC#%WDw5sLFT%a|ov_SD@ZzW(&J>Xt z2eF9zL|$kAq4Hh!#18ZELF#4OYYgl1!l@ZcjNj6XdJ8A+1fN;A&DMd}?JP&B&@xs( z7@9UQUzH%ur#7dbhqqq(4#ln(>Z+s`6s!&JlO!k}DCtb;URm0KSLYl?S|uD3flro6 zRM&J^C}d3Czl+3QOBJS6JqsF|_>rmPm7ej)#A+F?mT z$h?! z0*ew|$#k1Y=geFLs;hl6VtI}%nsaEzAyQ8U_01p^cu~Lom8y!2l-(t_N--}Rzva~5 zJ3k);nR0sY0+2{h<+QPu0zG9aYR@W_e=I`fKm2blKB~N+=CcG|P^{XAdD?eJQbo7& zwZVpzTr_(C^XC8%Kcz!}DlaqpgDa@d&F zD#|)%^e5xhK27@m^h7a;Nki7emd6VgZYeXNynq)%p<|c1slpoiui`O)U9+CC_%IB> zSo^a$q8*hI$ZX|2%=)cl=gbVJ-j_g&JCMH?@w_wU&a4gUN+2n_37fRLtS!wgz|eJ8 zTE4%f2Wa8eqH$S@Adm%$)_E;^_>=KOd}YFHns-CNVrCo0ezL;G(!3qIlY|_*`{H); zCZ0>D0N!Ec$VwnnipxL4+MD8%&OJe=o3drrw{F5vH;?-U-#4FR8^N?1>;%J-M;r9- zCmZF+OQ~3S{0Y6w+L*HJ+p~y-m-WJ(i3VP1TY>jj`r2xB-a74TL6d_rYU|=BP3Qg^ zIr7Wh>a2Q4CfO~B5UH&tw;zMo9s?{pAeVY_yHa|-5^LAJ0-H_~48$3-JpatLp%?e> zZ=WnrTJ^pty2KUs)phK@ceO$FZDqHT;`9JyZERE?C$QhH{Yo$~7?uwl8Tfyjc9P+I Y$WCci0}NJe34R4a&i3wzMz~+v-vdkt*Z=?k diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png deleted file mode 100644 index 6902aa839d7f734da5edd7503036f9b21f6bf185..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4837 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 b0RammQpjyze3v!aav`gtqzNfguzLD`Vq+eC diff --git a/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png b/BookPlayer/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png deleted file mode 100644 index ff16f31ef5f56d9f046a784e3ce210fc63ff86f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5376 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 diff --git a/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/Contents.json b/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/Contents.json index 10560d605..4143c2759 100644 --- a/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/Contents.json +++ b/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/Contents.json @@ -1,116 +1,37 @@ { "images" : [ { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "icon_83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", "filename" : "Icon.png", - "scale" : "1x" + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "Icon 1.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } } diff --git a/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/Icon 1.png b/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/Icon 1.png new file mode 100644 index 0000000000000000000000000000000000000000..ba050eb57a1347905626c9f98676b00216a2f6be GIT binary patch literal 89603 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 z≪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 TOs>R1z>kW8rhKlf`OE(YB?boY literal 0 HcmV?d00001 diff --git a/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_20pt.png b/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_20pt.png deleted file mode 100644 index 3ea4080a0ccdfe45110a3a3027a7a4a94e7480cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 500 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 diff --git a/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_29pt.png b/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_29pt.png deleted file mode 100644 index 7c39d36531224799c987485fede6ba3d055151bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 785 zcmV+s1Md8ZP)k3_+3Tz*o_xZ4 ze@ALdr}uWwIaAb;f_Z_rvuCZQVSajQFFvFzIihENdS41a1$CrgK!ShFOPK!$Rxf6D zu0rGcJpQ+6V)OclqFk#`4zn zpx>z${r*R~=aO#awq4e;E*mm`v#<7D2y)j!ocAj z-C(^T4I6x~0(-nGE5|~BdVPJ{9UU7B3MY|*p)k783j?S3f<4}PzV}}R_IS6p&ZNA` zDn+qz{lz6yNWoATUFe13^~VdTxp_@q{siaozW(}Z>y#xY4;dL%N?u>q3&ZQ5hyUJX z1qO9K^gO)g`PI@cd(HDZyL>^>M*n zqXU~l3~N+SM=CXc?+^J>>XrWK=w7XBT9}>PXZMT9-j#(zDF7AJk%9q9_X~QY%#k+P z{|k#p_BRGQ*#7PXXNo#fFjxzu-!mspWd9%L#F}jX@W%aEBqjTw$=*-oP#IFu@xD#^ z9gNI*965N8wdnf3P5Ld_|BJauBm3{k?$=o&;*CN>q3BK2pBIKe1{?tZwqwP#+*u80 P00000NkvXXu0mjfLt=!Z diff --git a/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_29pt@2x.png b/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_29pt@2x.png deleted file mode 100644 index b88b6ad6b6266d99a01bdd02d047ba0469011b01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1784 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 K)mmlSsQ&@Q(dzmD diff --git a/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_60pt@2x.png b/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_60pt@2x.png deleted file mode 100644 index 632d3d0532dbde994cfd07a8ba3c1c288b52b36b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4117 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 K)mmlSsQ&@Q(dzmD diff --git a/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_60pt@3x.png b/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_60pt@3x.png deleted file mode 100644 index 5239c4b4961ba8eecb57b337e490ec2f79c8c6f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6568 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 I{B7|60b~TJApigX diff --git a/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_76pt.png b/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_76pt.png deleted file mode 100644 index e860d1d6646de42c553eed98f4b40c3b9ed7fce0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2419 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 diff --git a/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_83.5@2x.png b/BookPlayer/Assets.xcassets/AppIcon.beta.appiconset/icon_83.5@2x.png deleted file mode 100644 index 49cfe658688aa07ce9771a4c93135e4affc0220c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6040 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 diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/Contents.json b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/Contents.json index 10560d605..4143c2759 100644 --- a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/Contents.json +++ b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/Contents.json @@ -1,116 +1,37 @@ { "images" : [ { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "icon_20pt@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "icon_29pt@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "icon_40pt@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "icon_60pt@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "icon_20pt@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "icon_29pt@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "icon_40pt@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "icon_76pt@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "icon_83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", "filename" : "Icon.png", - "scale" : "1x" + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "Icon 1.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } } diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/Icon 1.png b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/Icon 1.png new file mode 100644 index 0000000000000000000000000000000000000000..935dbd1ac6d2ace92afa410cf01b2889b14cd769 GIT binary patch literal 88839 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⋁aSPwHqBIUX%Z{hbHDZ$zNG|dk7C628AIZVgZ11>` z(|s4r=bCmEZG6&iU*Cyj1<`Vr^Rv!rY?cV7?REKtDVAWNiICu|W7qoq@uR)lZ`aeN zS<|3Gm)y%${{Z0&hXY%Jx|H&%>ga=*@sKLruxCT4H?kKP1``R9ij-yye~|#G#6n6o z{@#OdaBqf5Se1yTLnEf0qj-R{2g38*XEp4P)j*|)W)$r8H1)%e#18lFkby#tHTfpb z=U2P#w43aOf1FJc8C|l!$10c!6pDD68+Y1C0I(n(SIp``d>l{@~tl!c{a@wLL`* z2|2I#B{93}{av;4fD0+jsQv#87wp{!;nN@W${@%Gj6nwWq(Gg2MC zua@$F%_*M~aUxBd0Kn`T=+CFu&gz3}_wAL~kt|Z++F)xy%qf3;xD1vG7!2HCaA5&p z$;EAhi+`X)>VWP(a5S?bS&Be2_l~4zry^Yh()QL9z9GS~*X1;**2K)vY2rirPmO1t z=xlTbBpk|9rzYVCd}U*88v^l_0q`FnMFRc|n&lAmv@-vdgqWPZ5KY+NP{(wdZA=j- zfUroxp|C0{0M>(Vm*f7lGgSiDm=@i_A-;|$xpaPISn9vpraNaWQm{yrm21O?fR){^gzNXx;=dk#MhAyl3*g18h85G9iaqV@6x9y z9dJa*i7QYqg(?3rPQ+_u&0f(D!2yTCk$H)WZ*C)Rg8sBjfqWQuf8U?J6+j5mN!IKr zqLGZSpQ0~ze}1?J*_%*KG7aq#2JCArv;v1^CR4p~B>kmMx$egJ#4m z1xv)qBw{496Z^+D%^+&%1hbyYqmj>n#F8jde%AleLP!~i(fsfBTX4kLo4_)Nujg<6 zu}rZ!2*fb&S}?)&wWv>%Q<^=n=(r0PfHI96beB?jmg~PF$#3fbC_iKxfWZ!Y z1Wx&nh<_l90F))mX#ro#Tt#XbQA%VyQphYG!xT{yx;>z{JtSNuD&eZ6Uk-kH`8*V7jBE$#)Fe06+ zB5&Q&OC}#&lBWLn_kZ|U^W}5xuOIcHVMDl~K#TBizyJVXfK}wxD;iSAxQRc0{qH~2 zXuV+s02p8udFg_R)IMhHk58YRcK7HGj~KSLY5n-A7A-~qfB{yK=g%of?V`qhi{)?M z>w|*_DHK+D#d=`SKtaI*LW}?a1FR~aiRH+#Ki<9I_U7KaLv;%_V_J{qS6|o@-Y$$$AEQbY;Yi&5WH2#0Ldhgp&0HMjGm&IlQO5eWHG0 z5Q)sj^0l4yd*vK0LW}_5J?W8d%+fSwTROCCk>FSIsG>y6QQwrxAMZQHiSc(!e4k{(a(*}5}5onh2d zw^DzcbAD-G6FX&?i4ro17Ysbub+b5Ae)r~U&oT%ggLq!xx9`~M#>-OWW6h+#vHW~N zsuZP`K60nW7HJ@c1xDBrG7GTLY{6gExu-G7B2;XO_`r^i*pox~DH7!Ncib@Or=3hp zv4|}QAcGhd@*;!+y@Q8ue8?PqUZHrERDEUFsi8xWBPU}?KKeCM&Gq?Op%;Tj5au z`cyDXEyL7c;Jgb9c@aWsrLtFEzy)F}cw2&u%*>V!WX-BzAumEG4Y6Lp*<&wAx+P9R z=FrXUvjxLKUW8B@Vm*N^77OW6o1?{6@Fv$sjFY@^lk5Kp7V;v53q-hEu+eM>Z;TX? zIb=hdbF{Bt<;cjrj~{h3&CF6PUDjX+Z?qmULbyPLy9FCecJTU$aT~bRff^84tyDgN zesWSzD@TtF-n{k3$G4KEu#guaTp+^Tf^|l-GnhN#P^NbIil#MdTP|OI0Wk+IC{%CW z(q2=0DJ4}(N?4r1dXHfH5pM{$f!ABXdj1QG2VT9V`QpXri6 z0R|3_6GFH^gwO5;g13R!7s%101GvU>e}UkoCgdyA<3}QE?70vh3B>X#=4%%n!TF*W zLVOkx%cp9BesBcii%rsfkW$q5K2QVpXvfUWNr3dCstkFIlbB2x~A#Op}w3% zaaYq-?qz}jrdY%l1pH2Qq&qyGJwuC`E{9?pjE))l8}mi;a) zn12tmNhjFo1KN~RG!+o+{N%7P2PcAl6c+4EbyxoZF&UmBH5m_o00000NkvXXu0mjf D_{SbO diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_20pt@3x.png b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_20pt@3x.png deleted file mode 100644 index 73112229c8a7d60e98190a81294da808166a2e9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1824 zcmX|CdpHyP7oU=Bu33}hHq1408IxPNUusjV<$iDOlv~U-#!{$X6jScyMaW&ei7gR} z=2eCv*JkAs#$1Y5z0a?6p6@yToO7PfbI#}aeA6zWEcig8AOHZsXJu(>dyw^iJ?=vX zv8ezB0|2-fR;EViD2^p!O337haM$k9_Lf)VYpK^;`ErN{*6M-%WnbpJCi5REv$qb* zBg7Pk|L3ivxt?{+jZRbEb4a3Su>Nyzibf;JU1TAvJbR4U3&o4ct%F?bCfQ%(YuJ>M zJqh4*VIgiPp?BQ)+eT`gI;?{zHj#+_NVnMD_;lFrgNdf>6Jfa@@wqZd;*KoOsHMxH zOToiVEA=z=63=W;O}nL`UxyCSshSnQv2u`HZ4xxlBa@r;UX(TRQm8C;0+$=Mc4@Ji zry^TQyAkuOJ}PZiP}KL_oZ2l&ggG_6$SD;~M1mm`Ys=~p0W?lAzt(Dj>n@Cre%RLH z^vfQE#@Wn7_A@UTke%{k7qsSR|NZmaXD_A)9>eS4r9}aORO^gA2kibV%dke33$7!9 z8VS|#`!G5ulk*SC#VW#qvC>D|N&HDCzsR?Wzk%qP^)vFJD>RYiB4-3esi|03Zm>N` zuvyK5GimD*0Fcaqv#gwdTi)QR^^L!Ky$NgczAz!$!6BMHihEJdc4+CN-N=yS*4E=H z7?E6`a>QP<5?~}l0zKvVi#dXPQ#p;_c^p#ynl6>c!^^dhc?<$6#JM4>udduNFSzk@ z=~~cIP{_B2G1AS3uv+%6?Qu+PTD}gR%MMaiu9@VkswPr&>S#7P_D2M)$+gJ<6g`sy zPRncL!+bnx1V16dOVx@4DH*PnpaJb#LeUMjwIu@o(HUO$iL=?Y1^IcQP_Mu|zl^j9~u}uEXJu$p9Qpg+y$=xffMNtKk`M zQ+c2)`5EL-HtE1!86Q0xyfSq(Jj1*t#)kLI|J!)NOGO&nW~8)9?ws!@Xu{9Nvo7=3itFu@g#nY1W6 z;v@RsF%*p##1Wj-W}TsQYUkUg*Krne^Ax6w%d9^9_c?<>dT@iGXia=~`)wqGU3&^q z@91QqVkGnKIF6)xFNPgPAk5pZvQGB^G~{zEDi;Xh>6h9w$u!nY)z40FoLnY}1P zZbo57XzL!aZ$a91U_zNX2ap$9r_g9zosc)^6J3eOKy3uy0O>}kZ4PeiV=E3DSi@$O z{8Nwz+5s=(>nB%C!Y|mh0}gPhTYKBO^dc+S=}u43pZ|s}er3wOH%JCTz_wnSK7a#x zpe181r5fQCnZK1LJ9jud-fcYY!OdyYndIju6Q`7A>a6B$1o(?@ZJO|d?JqM{fe)Ga z@)O@10%?v|U(?r{3MtH(!umU3<1;WJtkUvVwJ}PDzNJdJouJg(l(W);-Z+L8E%q;! z0gu$~LpLif_J_!seF`ImNHSWqGj0bkldzT-6M9Kv$GW?;-2#NjPnR)$3 zsEwAk9i{6OfmV0B_|U&~$ye9djN`cJ6GN-^;^3#%3J(fLVf2-Ev#LtIp_%#n)TeL# zc{H9qt|DawIA%$7EEFlKPlX2|ZF}6*yP5udbr##-rD0{%y9zrySlPb`H3grFh0tO^_8iawxJHGMc1QQ;QZ1!I;7<3@qNERgO2XcJ;|C z%Xz(viw7?NdA+<^?Ck1t^TyDEAsADbg@M(3iY}<;$txhsdA;lF#|*E6Vt!O~PeI{0 zS}+7-3bQc${PjX=Vp5r%Gs^aQfARThXci|V^y}-Fz5jeUUKoD#_w#T2`1kO= z->bfNJ)jPj?@$r6;lFeo82VtdxxBCGGk{Fqv~mB=*HFRdsVzrDG`EgmCb-Dfb6^qu$S?wvkAOHXW diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_29pt@2x.png b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_29pt@2x.png deleted file mode 100644 index 329271f919c3aff652a3c9e7de8fb0e461c3d706..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1749 zcmV;`1}gc9P)&Op5XSEhDz^h=hA=Z6^IiCunVFfw%*-6;!pzKUhm7slQRn%|v2}joOrzQ9tfbxV z`&B39N$U-Nuc>Vv_y3B!j=PS#j@wu}SXt7eRH|4T(Sk;_FCXsM$n>+@`H0xi>X~Vo z{*5R`3)c&grNWiTm4(IKRW$=hu-n!=0zWPSUzUsxPw69qG8B_Wh;Yh~g*cK$!xfcu zU%HutxN$!}A*CrZy#;V9S)i5=&2?7b2Zj^2q|4ktUhhT2;CJK6-e+68jnJ6%Ih z_{874k{uCHIW;NeM37(?2XP7oTqRo2h<1oT3WA*S&I`G;BLEn1MeP#0dF$ycD3UO- z2{bT#$AyvcJ2O*XD|0_PD}N`O0Jj~HH!o)Pc26LXU>65*3I!-bF=>PdtqBX-5daLh z*-aC4^QIFSw6w9MKm2rsv9Yg(9Mve!@y{vtO$r`$kL7gV89J6RpZ`G>*4Drd=SOaDKsLo7XKA4gA}a{ zBVq~w2HfD1VbXagwVM{TbB`B>*t{j8w^t02D_3*4Bc5IfnVD@SbMAOZ(aJC)rT}2T z#p*&jZzp%@kGpGk^vK8*Cvx>#E_cwvGN7ShC@-%=qu7>@3nO9*00vzDVm0oqWPPu$ zhi8IVJd1W3*UCE3$k^A$HfUsI8rNIk>cWVa0)PS6PekD+@vg3|8xPmgDiA=3<0n#Q zX5{GAz>SM*NKI`)a{YR4f4_w8g%qs}BVq~w23+4FHSSH_xbX>%TH9${2geXx*XuX( zaPLk|N^u|S!o5l10)PScUD2Q#H?fmO5Ll@bH-V44Qa3|n zWLs*9w*%x8FMc{wq z(PPmE7U2{%E&v#CgWeCTaW!6XJQ7%6aa>%(2s#~*;^9)SH~?V44JlRQ-b?SD?+auI z(+ebwh$#RVaKp=1`1KqB47gDhJX{B#|1;)|jx=#6Qn(}hh7nf}LqApJK_QQg-tk(RT zb{LcJeOf%wClOXa0m|quh(HR0oH8slpDlyW#FpR4McK@_3WciZeRoaWAQFwAQbOOB zi6>_D5kVP>HGWEgAY>tqgvV<8qr9?s`ug#iyJx2_AEI#Cw~?VK&N4o{79U~yH=-CV zTrWiEQ#9-J#RIdxkHtox&pf^=FUeOl)+`7YTYdFFO?lt^eg;G%+I6vtt-e+EbWZNF zoVj}reAq=!D#E4L0(pM=^ci&}!KY%AuaK`UT;5t>`~`^doXPUi$UU%%aA{UTEXz!s r^l(PLx^M|AQ*2lptOR!ru_FEf^oYL@L5+z500000NkvXXu0mjf;aDxQ diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_29pt@3x.png b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_29pt@3x.png deleted file mode 100644 index bbda9238f8524460218884ca1c1484edb40620fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2832 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 D_{SbO diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_40pt@2x.png b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_40pt@2x.png deleted file mode 100644 index b273e9c7f73f720fa26d5455edadaf82581a26ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2597 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 DDS(P` diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_60pt@2x.png b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_60pt@2x.png deleted file mode 100644 index 12d61f56a77916cbbb2576c25d4e7079dcd3646b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4066 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 DDS(P` diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_60pt@3x.png b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_60pt@3x.png deleted file mode 100644 index fb4eb3135be221729886808e6dc413fbb0589f56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6516 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 IQYOLw1AthrV*mgE diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_76pt.png b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_76pt.png deleted file mode 100644 index 27573d76ceaf2820081df06f065d1f9199cb2539..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2397 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 P00000NkvXXu0mjfb4qmw diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_76pt@2x.png b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_76pt@2x.png deleted file mode 100644 index 13c19618fb0087985923ee7ed9d3bef77e780ffe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5414 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 diff --git a/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_83.5@2x.png b/BookPlayer/Assets.xcassets/AppIcon.debug.appiconset/icon_83.5@2x.png deleted file mode 100644 index e36fb03d583650221d42efcbe7d228ac78251631..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5977 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 Date: Fri, 27 Sep 2024 21:41:29 -0500 Subject: [PATCH 02/18] Add swift format rules --- .swift-format | 10 ++ .swiftlint.yml | 1 + BookPlayer.xcodeproj/project.pbxproj | 4 + BookPlayer/AppDelegate.swift | 241 +++++++++++++++++---------- 4 files changed, 165 insertions(+), 91 deletions(-) create mode 100644 .swift-format diff --git a/.swift-format b/.swift-format new file mode 100644 index 000000000..d0f97b7a9 --- /dev/null +++ b/.swift-format @@ -0,0 +1,10 @@ +{ + "version": 1, + "lineLength": 120, + "indentation": { + "spaces": 2 + }, + "maximumBlankLines": 1, + "lineBreakBeforeEachArgument": true, + "prioritizeKeepingFunctionOutputTogether": true +} diff --git a/.swiftlint.yml b/.swiftlint.yml index babd5d0b7..1168e0474 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -19,3 +19,4 @@ disabled_rules: - file_length - orphaned_doc_comment - large_tuple + - opening_brace diff --git a/BookPlayer.xcodeproj/project.pbxproj b/BookPlayer.xcodeproj/project.pbxproj index e1b3dabb5..8456e6232 100644 --- a/BookPlayer.xcodeproj/project.pbxproj +++ b/BookPlayer.xcodeproj/project.pbxproj @@ -382,6 +382,7 @@ 638E64CC2B8E086400DCFA3B /* RealmManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E64CA2B8E086400DCFA3B /* RealmManager.swift */; }; 638E64CE2B8E1CFD00DCFA3B /* SyncTasksCountService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E64CD2B8E1CFD00DCFA3B /* SyncTasksCountService.swift */; }; 638E64CF2B8E1CFD00DCFA3B /* SyncTasksCountService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E64CD2B8E1CFD00DCFA3B /* SyncTasksCountService.swift */; }; + 6397206F2CA71D600045A4DB /* .swift-format in Resources */ = {isa = PBXBuildFile; fileRef = 6397206E2CA71D600045A4DB /* .swift-format */; }; 6399F94D2AA03C6C00A5C8EA /* BPSKANManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */; }; 639AC9892AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; 639AC98A2AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; @@ -1158,6 +1159,7 @@ 63833DF92AAC139700496246 /* PlaybackPerformanceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaybackPerformanceTests.swift; sourceTree = ""; }; 638E64CA2B8E086400DCFA3B /* RealmManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealmManager.swift; sourceTree = ""; }; 638E64CD2B8E1CFD00DCFA3B /* SyncTasksCountService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTasksCountService.swift; sourceTree = ""; }; + 6397206E2CA71D600045A4DB /* .swift-format */ = {isa = PBXFileReference; lastKnownFileType = text; path = ".swift-format"; sourceTree = ""; }; 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPSKANManager.swift; sourceTree = ""; }; 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPDownloadURLSession.swift; sourceTree = ""; }; 639E12C52B85AACF00C875F7 /* SyncTasksObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTasksObject.swift; sourceTree = ""; }; @@ -2740,6 +2742,7 @@ C35BADE7206989E6007687C1 /* LICENSE */, C35BADE9206989E6007687C1 /* .swiftlint.yml */, C3EA7175218DEC870005D488 /* .swiftformat */, + 6397206E2CA71D600045A4DB /* .swift-format */, ); name = Meta; sourceTree = ""; @@ -3183,6 +3186,7 @@ 41AD3D9A221C737F00DC41E1 /* retro-icon@2x.png in Resources */, 419B373F23B8D14100128A8F /* LoadingView.xib in Resources */, 9F665EDE2A4898F6004BFE27 /* heart-of-glass-ayu@2x.png in Resources */, + 6397206F2CA71D600045A4DB /* .swift-format in Resources */, C3EA7176218DEC870005D488 /* .swiftformat in Resources */, 41E562FC2239535D00C06BC9 /* neon-ipad@2x.png in Resources */, 41E562D222394F5A00C06BC9 /* dark@2x.png in Resources */, diff --git a/BookPlayer/AppDelegate.swift b/BookPlayer/AppDelegate.swift index 76dc9339d..bddec417a 100644 --- a/BookPlayer/AppDelegate.swift +++ b/BookPlayer/AppDelegate.swift @@ -14,9 +14,9 @@ import CoreData import DirectoryWatcher import Intents import MediaPlayer -import Sentry import RealmSwift import RevenueCat +import Sentry import StoreKit import UIKit import WatchConnectivity @@ -44,7 +44,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { if let scene = UIApplication.shared.connectedScenes.first( where: { $0.activationState == .foregroundActive } ) as? UIWindowScene, - let delegate = scene.delegate as? SceneDelegate { + let delegate = scene.delegate as? SceneDelegate + { return delegate } else { return lastSceneToResignActive @@ -54,9 +55,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { private var crashReportsAccessObserver: NSKeyValueObservation? private var sharedWidgetActionURLObserver: NSKeyValueObservation? /// Background refresh task identifier - private lazy var refreshTaskIdentifier = "\(Bundle.main.configurationString(for: .bundleIdentifier)).background.refresh" + private lazy var refreshTaskIdentifier = + "\(Bundle.main.configurationString(for: .bundleIdentifier)).background.refresh" - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { Self.shared = self NotificationCenter.default.addObserver( @@ -84,7 +89,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { return true } - func application(_ application: UIApplication, handle intent: INIntent, completionHandler: @escaping (INIntentResponse) -> Void) { + func application( + _ application: UIApplication, + handle intent: INIntent, + completionHandler: @escaping (INIntentResponse) -> Void + ) { let response: INPlayMediaIntentResponse do { try ActionParserService.process(intent) @@ -196,14 +205,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { let fileURL = DataManager.getProcessedFolderURL().appendingPathComponent(relativePath) if syncService?.isActive == false, - !FileManager.default.fileExists(atPath: fileURL.path) { - alertPresenter.showAlert("file_missing_title".localized, message: "\("file_missing_description".localized)\n\(fileURL.lastPathComponent)", completion: nil) + !FileManager.default.fileExists(atPath: fileURL.path) + { + alertPresenter.showAlert( + "file_missing_title".localized, + message: + "\("file_missing_description".localized)\n\(fileURL.lastPathComponent)", + completion: nil + ) return } // Only load if loaded book is a different one if playerManager?.hasLoadedBook() == true, - relativePath == playerManager?.currentItem?.relativePath { + relativePath == playerManager?.currentItem?.relativePath + { if autoplay { playerManager?.play() } @@ -218,15 +234,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { do { /// If the selected item is a bound book, check that the contents are loaded if syncService?.isActive == true, - libraryItem.type == .bound, - let contents = libraryService?.getMaxItemsCount(at: relativePath), - contents == 0 { + libraryItem.type == .bound, + let contents = libraryService?.getMaxItemsCount(at: relativePath), + contents == 0 + { _ = try await syncService?.syncListContents(at: relativePath) } item = try self.playbackService?.getPlayableItem(from: libraryItem) } catch { - alertPresenter.showAlert("error_title".localized, message: error.localizedDescription, completion: nil) + alertPresenter.showAlert( + "error_title".localized, + message: error.localizedDescription, + completion: nil + ) return } @@ -247,7 +268,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { @objc func messageReceived(_ notification: Notification) { guard let message = notification.userInfo as? [String: Any], - let action = CommandParser.parse(message) else { + let action = CommandParser.parse(message) + else { return } @@ -261,7 +283,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { let playerManager = self.playerManager, playerManager.currentItem != nil else { - UIAccessibility.post(notification: .announcement, argument: "voiceover_no_title".localized) + UIAccessibility.post( + notification: .announcement, + argument: "voiceover_no_title".localized + ) return false } @@ -270,90 +295,102 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } func setupMPRemoteCommands() { - self.setupMPPlaybackRemoteCommands() - self.setupMPSkipRemoteCommands() + Task { + self.setupMPPlaybackRemoteCommands() + self.setupMPSkipRemoteCommands() + } } func setupMPPlaybackRemoteCommands() { - Task { - // Play / Pause - MPRemoteCommandCenter.shared().togglePlayPauseCommand.isEnabled = true - MPRemoteCommandCenter.shared().togglePlayPauseCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { return .commandFailed } - - let wasPlaying = playerManager.isPlaying - playerManager.playPause() - - if wasPlaying, - UIApplication.shared.applicationState == .background { - self?.scheduleAppRefresh() - } - return .success + let center = MPRemoteCommandCenter.shared() + // Play / Pause + center.togglePlayPauseCommand.isEnabled = true + center.togglePlayPauseCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + guard let playerManager = self?.playerManager else { + return .commandFailed } - - MPRemoteCommandCenter.shared().playCommand.isEnabled = true - MPRemoteCommandCenter.shared().playCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { return .commandFailed } - - playerManager.play() - return .success + + let wasPlaying = playerManager.isPlaying + playerManager.playPause() + + if wasPlaying, + UIApplication.shared.applicationState == .background + { + self?.scheduleAppRefresh() } - - MPRemoteCommandCenter.shared().pauseCommand.isEnabled = true - MPRemoteCommandCenter.shared().pauseCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { return .commandFailed } - - playerManager.pause() - - if UIApplication.shared.applicationState == .background { - self?.scheduleAppRefresh() - } - - return .success + return .success + } + + center.playCommand.isEnabled = true + center.playCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + guard let playerManager = self?.playerManager else { + return .commandFailed } - - MPRemoteCommandCenter.shared().changePlaybackPositionCommand.isEnabled = true - MPRemoteCommandCenter.shared().changePlaybackPositionCommand.addTarget { [weak self] remoteEvent in - guard - let playerManager = self?.playerManager, - let currentItem = playerManager.currentItem, - let event = remoteEvent as? MPChangePlaybackPositionCommandEvent - else { return .commandFailed } - - var newTime = event.positionTime - - if UserDefaults.sharedDefaults.bool(forKey: Constants.UserDefaults.chapterContextEnabled), - let currentChapter = currentItem.currentChapter { - newTime += currentChapter.start - } - - playerManager.jumpTo(newTime, recordBookmark: true) - - return .success + + playerManager.play() + return .success + } + + center.pauseCommand.isEnabled = true + center.pauseCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + guard let playerManager = self?.playerManager else { + return .commandFailed } + + playerManager.pause() + + if UIApplication.shared.applicationState == .background { + self?.scheduleAppRefresh() + } + + return .success + } + + center.changePlaybackPositionCommand.isEnabled = true + center.changePlaybackPositionCommand.addTarget { [weak self] remoteEvent in + guard + let playerManager = self?.playerManager, + let currentItem = playerManager.currentItem, + let event = remoteEvent as? MPChangePlaybackPositionCommandEvent + else { return .commandFailed } + + var newTime = event.positionTime + + if UserDefaults.sharedDefaults.bool(forKey: Constants.UserDefaults.chapterContextEnabled), + let currentChapter = currentItem.currentChapter + { + newTime += currentChapter.start + } + + playerManager.jumpTo(newTime, recordBookmark: true) + + return .success } } // For now, seek forward/backward and next/previous track perform the same function func setupMPSkipRemoteCommands() { + let center = MPRemoteCommandCenter.shared() // Forward - MPRemoteCommandCenter.shared().skipForwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.forwardInterval)] - MPRemoteCommandCenter.shared().skipForwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + center.skipForwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.forwardInterval)] + center.skipForwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in guard let playerManager = self?.playerManager else { return .commandFailed } playerManager.forward() return .success } - MPRemoteCommandCenter.shared().nextTrackCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + center.nextTrackCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in guard let playerManager = self?.playerManager else { return .commandFailed } playerManager.forward() return .success } - MPRemoteCommandCenter.shared().seekForwardCommand.addTarget { [weak self] (commandEvent) -> MPRemoteCommandHandlerStatus in - guard let cmd = commandEvent as? MPSeekCommandEvent, cmd.type == .endSeeking else { + center.seekForwardCommand.addTarget { [weak self] (commandEvent) -> MPRemoteCommandHandlerStatus in + guard let cmd = commandEvent as? MPSeekCommandEvent, + cmd.type == .endSeeking + else { return .success } @@ -365,23 +402,26 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } // Rewind - MPRemoteCommandCenter.shared().skipBackwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.rewindInterval)] - MPRemoteCommandCenter.shared().skipBackwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + center.skipBackwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.rewindInterval)] + center.skipBackwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in guard let playerManager = self?.playerManager else { return .commandFailed } playerManager.rewind() return .success } - MPRemoteCommandCenter.shared().previousTrackCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in + center.previousTrackCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in guard let playerManager = self?.playerManager else { return .commandFailed } playerManager.rewind() return .success } - MPRemoteCommandCenter.shared().seekBackwardCommand.addTarget { [weak self] (commandEvent) -> MPRemoteCommandHandlerStatus in - guard let cmd = commandEvent as? MPSeekCommandEvent, cmd.type == .endSeeking else { + center.seekBackwardCommand.addTarget { [weak self] (commandEvent) -> MPRemoteCommandHandlerStatus in + guard + let cmd = commandEvent as? MPSeekCommandEvent, + cmd.type == .endSeeking + else { return .success } @@ -394,7 +434,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } func setupRevenueCat() { - let revenueCatApiKey: String = Bundle.main.configurationValue(for: .revenueCat) + let revenueCatApiKey: String = Bundle.main.configurationValue( + for: .revenueCat + ) Purchases.logLevel = .error Purchases.configure(withAPIKey: revenueCatApiKey) } @@ -402,12 +444,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { /// Setup observer for user preference, and setup Sentry based on initial value func setupSentry() { let userDefaults = UserDefaults.standard - crashReportsAccessObserver = userDefaults.observe(\.userSettingsCrashReportsDisabled) { [weak self] object, _ in - self?.handleSentryPreference(isDisabled: object.userSettingsCrashReportsDisabled) + crashReportsAccessObserver = userDefaults.observe( + \.userSettingsCrashReportsDisabled + ) { [weak self] object, _ in + self?.handleSentryPreference( + isDisabled: object.userSettingsCrashReportsDisabled + ) } handleSentryPreference( - isDisabled: userDefaults.bool(forKey: Constants.UserDefaults.crashReportsDisabled) + isDisabled: userDefaults.bool( + forKey: Constants.UserDefaults.crashReportsDisabled + ) ) } @@ -425,15 +473,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { if let actionURL = sharedDefaults.sharedWidgetActionURL { ActionParserService.process(actionURL) - sharedDefaults.removeObject(forKey: Constants.UserDefaults.sharedWidgetActionURL) + sharedDefaults.removeObject( + forKey: Constants.UserDefaults.sharedWidgetActionURL + ) } - sharedWidgetActionURLObserver = sharedDefaults.observe(\.sharedWidgetActionURL) { defaults, _ in + sharedWidgetActionURLObserver = sharedDefaults.observe( + \.sharedWidgetActionURL + ) { defaults, _ in DispatchQueue.main.async { guard let actionURL = defaults.sharedWidgetActionURL else { return } ActionParserService.process(actionURL) - sharedDefaults.removeObject(forKey: Constants.UserDefaults.sharedWidgetActionURL) + sharedDefaults.removeObject( + forKey: Constants.UserDefaults.sharedWidgetActionURL + ) } } } @@ -483,7 +537,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } func requestReview() { - if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene { + if let scene = UIApplication.shared.connectedScenes.first(where: { + $0.activationState == .foregroundActive + }) as? UIWindowScene { SKStoreReviewController.requestReview(in: scene) } } @@ -510,7 +566,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } if let mainCoordinator = activeSceneDelegate?.mainCoordinator, - !mainCoordinator.hasPlayerShown() { + !mainCoordinator.hasPlayerShown() + { mainCoordinator.showPlayer() } } @@ -523,10 +580,12 @@ extension AppDelegate { func setupBackgroundRefreshTasks() { NotificationCenter.default.addObserver( forName: UIApplication.didEnterBackgroundNotification, - object: nil, queue: nil) { _ in - if self.playerManager?.isPlaying != true { - self.scheduleAppRefresh() - } + object: nil, + queue: nil + ) { _ in + if self.playerManager?.isPlaying != true { + self.scheduleAppRefresh() + } } BGTaskScheduler.shared.register( From cc608aa42b5dd6f3c5b3be51b6e266bc1e0bef1a Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Sun, 29 Sep 2024 08:49:01 -0500 Subject: [PATCH 03/18] Add nested chapter logic to set offset --- BookPlayer/Player/PlayerManager.swift | 147 +++++++++++------- Shared/CommandParser.swift | 5 +- .../Lightweight-Models/PlayableChapter.swift | 11 +- .../Lightweight-Models/PlayableItem.swift | 22 +-- Shared/Services/PlaybackService.swift | 88 ++++++----- 5 files changed, 163 insertions(+), 110 deletions(-) diff --git a/BookPlayer/Player/PlayerManager.swift b/BookPlayer/Player/PlayerManager.swift index 8c1d7a04e..659c40795 100755 --- a/BookPlayer/Player/PlayerManager.swift +++ b/BookPlayer/Player/PlayerManager.swift @@ -147,12 +147,12 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { isPlayingPublisher() .removeDuplicates() .sink { [weak self] isPlayingValue in - UserDefaults.sharedDefaults.set( - isPlayingValue, - forKey: Constants.UserDefaults.sharedWidgetIsPlaying - ) - self?.widgetReloadService.reloadWidget(.lastPlayedWidget) - }.store(in: &disposeBag) + UserDefaults.sharedDefaults.set( + isPlayingValue, + forKey: Constants.UserDefaults.sharedWidgetIsPlaying + ) + self?.widgetReloadService.reloadWidget(.lastPlayedWidget) + }.store(in: &disposeBag) } func bindInterruptObserver() { @@ -208,11 +208,13 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { let fileURL: URL if !forceRefresh, - let chapterURL = chapter.remoteURL { + let chapterURL = chapter.remoteURL + { fileURL = chapterURL } else { isFetchingRemoteURL = true - fileURL = try await syncService + fileURL = + try await syncService .getRemoteFileURLs(of: chapter.relativePath, type: .book)[0].url isFetchingRemoteURL = false } @@ -229,7 +231,7 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { "hasProtectedContent", "providesPreciseDurationAndTiming", "commonMetadata", - "metadata" + "metadata", ]) guard !Task.isCancelled else { @@ -238,10 +240,11 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { /// Load artwork if it's not cached if !ArtworkService.isCached(relativePath: chapter.relativePath), - let data = AVMetadataItem.metadataItems( + let data = AVMetadataItem.metadataItems( from: asset.commonMetadata, filteredByIdentifier: .commonIdentifierArtwork - ).first?.dataValue { + ).first?.dataValue + { await ArtworkService.storeInCache(data, for: chapter.relativePath) } @@ -262,7 +265,8 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { let asset: AVURLAsset if syncService.isActive, - !FileManager.default.fileExists(atPath: fileURL.path) { + !FileManager.default.fileExists(atPath: fileURL.path) + { asset = try await loadRemoteURLAsset(for: chapter, forceRefresh: forceRefreshURL) } else { asset = AVURLAsset(url: fileURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true]) @@ -392,7 +396,8 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { var pathForArtwork = chapter.relativePath if !ArtworkService.isCached(relativePath: chapter.relativePath), - let currentItem = currentItem { + let currentItem = currentItem + { pathForArtwork = currentItem.relativePath } @@ -412,7 +417,8 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { boundsSize: image.size, requestHandler: { (_) -> UIImage in image - }) + } + ) MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo } @@ -437,10 +443,13 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { } if currentItem.isBoundBook { - currentTime += currentItem.currentChapter.start - } else if currentTime >= currentItem.currentChapter.end || currentTime < currentItem.currentChapter.start, - let newChapter = currentItem.getChapter(at: currentTime), - newChapter != currentItem.currentChapter { + currentTime += (currentItem.currentChapter.start - currentItem.currentChapter.chapterOffset) + } + + if currentTime >= currentItem.currentChapter.end || currentTime < currentItem.currentChapter.start, + let newChapter = currentItem.getChapter(at: currentTime), + newChapter != currentItem.currentChapter + { /// Avoid setting the same chapter, as it would publish an update event currentItem.currentChapter = newChapter } @@ -469,8 +478,8 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { let playbackQueuedFlag = playbackQueued == true return controlStatusFlag - || playbackQueuedFlag - || (isFetchingRemoteURL == true && playbackQueuedFlag) + || playbackQueuedFlag + || (isFetchingRemoteURL == true && playbackQueuedFlag) } /// We need an intermediate publisher for the `timeControlStatus`, as the `AVPlayer` instance can be recreated, @@ -485,7 +494,8 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { func bindPauseObserver() { self.isPlayingSubscription?.cancel() - self.isPlayingSubscription = timeControlPassthroughPublisher + self.isPlayingSubscription = + timeControlPassthroughPublisher .delay(for: .seconds(0.1), scheduler: RunLoop.main, options: .none) .sink { timeControlStatus in if timeControlStatus == .paused { @@ -505,17 +515,18 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { let controlStatusFlag = timeControlStatus != .paused let playbackQueuedFlag = playbackQueued == true return controlStatusFlag - || playbackQueuedFlag - || (isFetchingRemoteURL == true && playbackQueuedFlag) + || playbackQueuedFlag + || (isFetchingRemoteURL == true && playbackQueuedFlag) }) .eraseToAnyPublisher() } var boostVolume: Bool = false { didSet { - self.audioPlayer.volume = self.boostVolume - ? Constants.Volume.boosted - : Constants.Volume.normal + self.audioPlayer.volume = + self.boostVolume + ? Constants.Volume.boosted + : Constants.Volume.normal } } @@ -555,7 +566,7 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { guard let currentItem = self.currentItem else { return } self.nowPlayingInfo[MPMediaItemPropertyTitle] = chapter.title - + /// If the chapter title is the same as the current item, show the author instead if chapter.title == currentItem.title { self.nowPlayingInfo[MPMediaItemPropertyArtist] = currentItem.author @@ -620,9 +631,10 @@ extension PlayerManager { let boundedTime = min(max(time, 0), currentItem.duration) - let newTime = currentItem.isBoundBook - ? currentItem.getChapterTime(in: currentItem.currentChapter, for: boundedTime) - : boundedTime + let newTime = + currentItem.isBoundBook + ? currentItem.getChapterTime(in: currentItem.currentChapter, for: boundedTime) + : boundedTime self.audioPlayer.seek(to: CMTime(seconds: newTime, preferredTimescale: CMTimeScale(NSEC_PER_SEC))) } @@ -642,19 +654,23 @@ extension PlayerManager { let chapterBeforeSkip = currentItem.currentChapter updatePlaybackTime(item: currentItem, time: boundedTime) if let chapterAfterSkip = currentItem.getChapter(at: boundedTime), - chapterBeforeSkip != chapterAfterSkip { + chapterBeforeSkip != chapterAfterSkip + { currentItem.currentChapter = chapterAfterSkip // If chapters are different, and it's a bound book, // load the new chapter - if currentItem.isBoundBook { + if currentItem.isBoundBook, + chapterBeforeSkip?.relativePath != chapterAfterSkip.relativePath + { loadChapterMetadata(chapterAfterSkip) return } } - let newTime = currentItem.isBoundBook - ? currentItem.getChapterTime(in: currentItem.currentChapter, for: boundedTime) - : boundedTime + let newTime = + currentItem.isBoundBook + ? currentItem.getChapterTime(in: currentItem.currentChapter, for: boundedTime) + : boundedTime self.audioPlayer.seek(to: CMTime(seconds: newTime, preferredTimescale: CMTimeScale(NSEC_PER_SEC))) } @@ -777,7 +793,8 @@ extension PlayerManager { let smartRewindEnabled = UserDefaults.standard.bool(forKey: Constants.UserDefaults.smartRewindEnabled) if smartRewindEnabled, - let lastPlayTime = item.lastPlayDate { + let lastPlayTime = item.lastPlayDate + { let timePassed = Date().timeIntervalSince(lastPlayTime) let timePassedLimited = min(max(timePassed, 0), Constants.SmartRewind.threshold) @@ -791,7 +808,7 @@ extension PlayerManager { self.audioPlayer.seek(to: CMTime(seconds: newPlayerTime, preferredTimescale: CMTimeScale(NSEC_PER_SEC))) } } - + func handleAutoTimer() { guard UserDefaults.standard.bool(forKey: Constants.UserDefaults.autoTimerEnabled) else { return } @@ -812,7 +829,12 @@ extension PlayerManager { // swiftlint:disable block_based_kvo // Using this instead of new form, because the new one wouldn't work properly on AVPlayerItem - override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) { + override func observeValue( + forKeyPath keyPath: String?, + of object: Any?, + change: [NSKeyValueChangeKey: Any]?, + context: UnsafeMutableRawPointer? + ) { guard let path = keyPath, path == "status", @@ -838,10 +860,11 @@ extension PlayerManager { self.playbackQueued = nil case .failed: if canFetchRemoteURL, - let nsError = item.error as? NSError, - (nsError.code == NSURLErrorResourceUnavailable - || nsError.code == NSURLErrorNoPermissionsToReadFile), - let currentItem { + let nsError = item.error as? NSError, + nsError.code == NSURLErrorResourceUnavailable + || nsError.code == NSURLErrorNoPermissionsToReadFile, + let currentItem + { loadAndRefreshURL(item: currentItem) canFetchRemoteURL = false } else { @@ -850,14 +873,14 @@ extension PlayerManager { if playbackQueued == true { if let nsError = item.error as? NSError { let errorDescription = """ - \(nsError.localizedDescription) + \(nsError.localizedDescription) - Error Domain - \(nsError.domain) + Error Domain + \(nsError.domain) - Additional Info - \(nsError.userInfo) - """ + Additional Info + \(nsError.userInfo) + """ showErrorAlert(title: "\("error_title".localized) \(nsError.code)", errorDescription) } else { showErrorAlert(title: "error_title".localized, item.error?.localizedDescription) @@ -983,7 +1006,8 @@ extension PlayerManager { func playNextItem(autoPlayed: Bool = false, shouldAutoplay: Bool = true) { /// If it's autoplayed, check if setting is enabled if autoPlayed, - !UserDefaults.standard.bool(forKey: Constants.UserDefaults.autoplayEnabled) { + !UserDefaults.standard.bool(forKey: Constants.UserDefaults.autoplayEnabled) + { return } @@ -1000,8 +1024,9 @@ extension PlayerManager { /// If autoplaying a finished book and restart is enabled, set currentTime to 0 if autoPlayed, - nextBook.isFinished, - restartFinished { + nextBook.isFinished, + restartFinished + { updatePlaybackTime(item: nextBook, time: 0) } @@ -1029,8 +1054,9 @@ extension PlayerManager { /// Only check for audiovisual content if a file extension is present if !fileExtension.isEmpty, - let fileType = UTType(filenameExtension: fileExtension), - !fileType.isSubtype(of: .audiovisualContent) { + let fileType = UTType(filenameExtension: fileExtension), + !fileType.isSubtype(of: .audiovisualContent) + { return getNextPlayableBook( after: nextBook, autoPlayed: autoPlayed, @@ -1047,17 +1073,20 @@ extension PlayerManager { currentItem: PlayableItem, after chapter: PlayableChapter ) -> PlayableChapter? { - guard let nextChapter = self.playbackService.getNextChapter( - from: currentItem, - after: chapter - ) else { return nil } + guard + let nextChapter = self.playbackService.getNextChapter( + from: currentItem, + after: chapter + ) + else { return nil } let fileExtension = nextChapter.fileURL.pathExtension /// Only check for audiovisual content if a file extension is present if !fileExtension.isEmpty, - let fileType = UTType(filenameExtension: fileExtension), - !fileType.isSubtype(of: .audiovisualContent) { + let fileType = UTType(filenameExtension: fileExtension), + !fileType.isSubtype(of: .audiovisualContent) + { return getNextPlayableChapter( currentItem: currentItem, after: nextChapter diff --git a/Shared/CommandParser.swift b/Shared/CommandParser.swift index 5f3d5d604..86739ae48 100644 --- a/Shared/CommandParser.swift +++ b/Shared/CommandParser.swift @@ -246,11 +246,12 @@ public class TimeParser { let durationFormatter = DateComponentsFormatter() durationFormatter.unitsStyle = .positional - durationFormatter.allowedUnits = [.minute, .second] durationFormatter.zeroFormattingBehavior = .pad durationFormatter.collapsesLargestUnit = false - if abs(time) > 3599.0 { + if abs(time) < 3600 { + durationFormatter.allowedUnits = [.minute, .second] + } else { durationFormatter.allowedUnits = [.hour, .minute, .second] } diff --git a/Shared/CoreData/Lightweight-Models/PlayableChapter.swift b/Shared/CoreData/Lightweight-Models/PlayableChapter.swift index 7b97c27d7..8b0e31beb 100644 --- a/Shared/CoreData/Lightweight-Models/PlayableChapter.swift +++ b/Shared/CoreData/Lightweight-Models/PlayableChapter.swift @@ -19,6 +19,7 @@ public struct PlayableChapter: Codable, Identifiable { public let relativePath: String public let remoteURL: URL? public let index: Int16 + public let chapterOffset: TimeInterval public var end: TimeInterval { return start + duration @@ -35,7 +36,8 @@ public struct PlayableChapter: Codable, Identifiable { duration: TimeInterval, relativePath: String, remoteURL: URL?, - index: Int16 + index: Int16, + chapterOffset: TimeInterval = 0 ) { self.title = title self.author = author @@ -44,14 +46,15 @@ public struct PlayableChapter: Codable, Identifiable { self.relativePath = relativePath self.remoteURL = remoteURL self.index = index + self.chapterOffset = chapterOffset } } extension PlayableChapter: Equatable { public static func == (lhs: PlayableChapter, rhs: PlayableChapter) -> Bool { return lhs.relativePath == rhs.relativePath - && lhs.index == rhs.index - && lhs.title == rhs.title - && lhs.start == rhs.start + && lhs.index == rhs.index + && lhs.title == rhs.title + && lhs.start == rhs.start } } diff --git a/Shared/CoreData/Lightweight-Models/PlayableItem.swift b/Shared/CoreData/Lightweight-Models/PlayableItem.swift index 8b481ca4b..0d925b89d 100644 --- a/Shared/CoreData/Lightweight-Models/PlayableItem.swift +++ b/Shared/CoreData/Lightweight-Models/PlayableItem.swift @@ -40,7 +40,7 @@ public final class PlayableItem: NSObject, Identifiable { enum CodingKeys: String, CodingKey { case title, author, chapters, currentTime, duration, - relativePath, parentFolder, percentCompleted, lastPlayDate, isFinished, isBoundBook + relativePath, parentFolder, percentCompleted, lastPlayDate, isFinished, isBoundBook } public init( @@ -74,12 +74,13 @@ public final class PlayableItem: NSObject, Identifiable { } public func getChapterTime(in chapter: PlayableChapter, for globalTime: TimeInterval) -> TimeInterval { - return globalTime - chapter.start + return globalTime - chapter.start + chapter.chapterOffset } public func getChapter(at globalTime: Double) -> PlayableChapter? { if let lastChapter = chapters.last, - lastChapter.end == globalTime { + lastChapter.end == globalTime + { return lastChapter } @@ -88,8 +89,8 @@ public final class PlayableItem: NSObject, Identifiable { public func currentTimeInContext(_ prefersChapterContext: Bool) -> TimeInterval { return prefersChapterContext - ? self.currentTime - self.currentChapter.start - : self.currentTime + ? self.currentTime - self.currentChapter.start + : self.currentTime } public func maxTimeInContext( @@ -116,14 +117,15 @@ public final class PlayableItem: NSObject, Identifiable { public func durationTimeInContext(_ prefersChapterContext: Bool) -> TimeInterval { return prefersChapterContext - ? self.currentChapter.duration - : self.duration + ? self.currentChapter.duration + : self.duration } public func getInterval(from proposedInterval: TimeInterval) -> TimeInterval { - let interval = proposedInterval > 0 - ? self.getForwardInterval(from: proposedInterval) - : self.getRewindInterval(from: proposedInterval) + let interval = + proposedInterval > 0 + ? self.getForwardInterval(from: proposedInterval) + : self.getRewindInterval(from: proposedInterval) return interval } diff --git a/Shared/Services/PlaybackService.swift b/Shared/Services/PlaybackService.swift index 21338e8bd..5553f6901 100644 --- a/Shared/Services/PlaybackService.swift +++ b/Shared/Services/PlaybackService.swift @@ -41,9 +41,10 @@ public final class PlaybackService: PlaybackServiceProtocol { item.lastPlayDate = now item.currentTime = time let progress = round((item.currentTime / item.duration) * 100) - let percentCompleted = progress.isFinite - ? progress - : 0 + let percentCompleted = + progress.isFinite + ? progress + : 0 item.percentCompleted = percentCompleted self.libraryService.updatePlaybackTime(relativePath: item.relativePath, time: time, date: now, scheduleSave: true) } @@ -71,10 +72,11 @@ public final class PlaybackService: PlaybackServiceProtocol { ) else { if let parentFolderPath = parentFolder { - let containerPathForParentFolder = self.libraryService.getItemProperty( - #keyPath(LibraryItem.folder.relativePath), - relativePath: parentFolderPath - ) as? String + let containerPathForParentFolder = + self.libraryService.getItemProperty( + #keyPath(LibraryItem.folder.relativePath), + relativePath: parentFolderPath + ) as? String return getPlayableItem( before: parentFolderPath, parentFolder: containerPathForParentFolder @@ -110,7 +112,8 @@ public final class PlaybackService: PlaybackServiceProtocol { var isUnfinished: Bool? if autoplayed == true, - !restartFinished { + !restartFinished + { isUnfinished = true } @@ -122,10 +125,11 @@ public final class PlaybackService: PlaybackServiceProtocol { ) else { if let parentFolderPath = parentFolder { - let containerPathForParentFolder = self.libraryService.getItemProperty( - #keyPath(LibraryItem.folder.relativePath), - relativePath: parentFolderPath - ) as? String + let containerPathForParentFolder = + self.libraryService.getItemProperty( + #keyPath(LibraryItem.folder.relativePath), + relativePath: parentFolderPath + ) as? String return getPlayableItem( after: parentFolderPath, parentFolder: containerPathForParentFolder, @@ -148,10 +152,12 @@ public final class PlaybackService: PlaybackServiceProtocol { } public func getFirstPlayableItem(in folder: SimpleLibraryItem, isUnfinished: Bool?) throws -> PlayableItem? { - guard let child = self.libraryService.findFirstItem( - in: folder.relativePath, - isUnfinished: isUnfinished - ) else { return nil } + guard + let child = self.libraryService.findFirstItem( + in: folder.relativePath, + isUnfinished: isUnfinished + ) + else { return nil } switch child.type { case .folder: @@ -289,34 +295,45 @@ public final class PlaybackService: PlaybackServiceProtocol { var currentDuration = 0.0 var index: Int16 = 0 - let chapters: [PlayableChapter] = items - .compactMap({ book in - let fileExtension = book.fileURL.pathExtension + var chapters = [PlayableChapter]() + for book in items { + /// nestd chapters need a way to set the nestedStart reference here in the building + var nestedChapters = try getPlayableChapters(book: book) + var hasNestedChapters = nestedChapters.count > 1 + var localDuration: TimeInterval = 0 + var localCurrentDuration: TimeInterval = 0 + + for nestedChapter in nestedChapters { + let fileExtension = nestedChapter.fileURL.pathExtension /// If file is not audiovisual content, don't include it as part of the playback item if !fileExtension.isEmpty, - let fileType = UTType(filenameExtension: fileExtension), - !fileType.isSubtype(of: .audiovisualContent) { - return nil + let fileType = UTType(filenameExtension: fileExtension), + !fileType.isSubtype(of: .audiovisualContent) + { + continue } - let truncatedDuration = TimeParser.truncateTime(book.duration) + let truncatedDuration = TimeParser.truncateTime(nestedChapter.duration) + localDuration = truncatedDuration index += 1 let chapter = PlayableChapter( - title: book.title, - author: book.details, + title: nestedChapter.title, + author: nestedChapter.author, start: currentDuration, duration: truncatedDuration, - relativePath: book.relativePath, - remoteURL: book.remoteURL, - index: index + relativePath: nestedChapter.relativePath, + remoteURL: nestedChapter.remoteURL, + index: index, + chapterOffset: nestedChapters.count == 1 ? 0 : localCurrentDuration ) - currentDuration = TimeParser.truncateTime(currentDuration + truncatedDuration) + localCurrentDuration = TimeParser.truncateTime(localCurrentDuration + localDuration) - return chapter - }) + chapters.append(chapter) + } + } guard !chapters.isEmpty else { throw BookPlayerError.runtimeError( @@ -334,9 +351,10 @@ public final class PlaybackService: PlaybackServiceProtocol { public func markStaleProgress(folderPath: String) { let defaults = UserDefaults.standard - var staleIdentifiers = defaults.stringArray( - forKey: Constants.UserDefaults.staleProgressIdentifiers - ) ?? [] + var staleIdentifiers = + defaults.stringArray( + forKey: Constants.UserDefaults.staleProgressIdentifiers + ) ?? [] guard !staleIdentifiers.contains(folderPath) else { return } @@ -349,7 +367,7 @@ public final class PlaybackService: PlaybackServiceProtocol { public func processFoldersStaleProgress() -> Bool { let defaults = UserDefaults.standard - guard + guard let staleIdentifiers = defaults.stringArray( forKey: Constants.UserDefaults.staleProgressIdentifiers ), From 563fca2978b1f94fde48d36ef57edf96ae0362db Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Mon, 30 Sep 2024 10:07:24 -0500 Subject: [PATCH 04/18] Cleanup comment --- Shared/Services/PlaybackService.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Shared/Services/PlaybackService.swift b/Shared/Services/PlaybackService.swift index 5553f6901..fe0eb953a 100644 --- a/Shared/Services/PlaybackService.swift +++ b/Shared/Services/PlaybackService.swift @@ -297,9 +297,8 @@ public final class PlaybackService: PlaybackServiceProtocol { var chapters = [PlayableChapter]() for book in items { - /// nestd chapters need a way to set the nestedStart reference here in the building - var nestedChapters = try getPlayableChapters(book: book) - var hasNestedChapters = nestedChapters.count > 1 + let nestedChapters = try getPlayableChapters(book: book) + /// Nested chapters need to calculate the offset they'll use as a reference var localDuration: TimeInterval = 0 var localCurrentDuration: TimeInterval = 0 From 04768ce21b463660f36600787b1ce820800ddb38 Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Mon, 30 Sep 2024 23:43:28 -0500 Subject: [PATCH 05/18] Add FUNDING.yml for Github Sponsors --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..b90313f55 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: GianniCarlo From 658f9820c010c6e41024ed7db0796ffd6e16f2b8 Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Tue, 1 Oct 2024 11:32:30 -0500 Subject: [PATCH 06/18] Rework last played widget small --- BookPlayer.xcodeproj/project.pbxproj | 48 +++- BookPlayer/Player/PlayerManager.swift | 40 +++- .../Settings/Themes Screen/ThemeManager.swift | 29 ++- .../logo-nobackground.imageset/Contents.json | 23 ++ .../logo-nobackground.png | Bin 0 -> 9617 bytes .../logo-nobackground@2x.png | Bin 0 -> 21234 bytes .../logo-nobackground@3x.png | Bin 0 -> 31265 bytes BookPlayerWidgets/BookPlayerWidgets.swift | 8 +- .../Phone/LastPlayed/LastPlayedProvider.swift | 129 +++++++++++ .../Phone/LastPlayed/LastPlayedView.swift | 107 +++++++++ .../LastPlayed/LastPlayedWidgetView.swift | 50 ++++ .../Phone/LastPlayedWidgetView.swift | 219 ------------------ .../Deprecated/RecentBooksProvider.swift | 82 +++++++ .../Deprecated}/RecentBooksWidgetView.swift | 99 ++------ BookPlayerWidgets/Phone/WidgetEntries.swift | 32 ++- Shared/Constants.swift | 10 +- .../WidgetLibraryItem.swift | 25 ++ 17 files changed, 579 insertions(+), 322 deletions(-) create mode 100644 BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/Contents.json create mode 100644 BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/logo-nobackground.png create mode 100644 BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/logo-nobackground@2x.png create mode 100644 BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/logo-nobackground@3x.png create mode 100644 BookPlayerWidgets/Phone/LastPlayed/LastPlayedProvider.swift create mode 100644 BookPlayerWidgets/Phone/LastPlayed/LastPlayedView.swift create mode 100644 BookPlayerWidgets/Phone/LastPlayed/LastPlayedWidgetView.swift delete mode 100644 BookPlayerWidgets/Phone/LastPlayedWidgetView.swift create mode 100644 BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksProvider.swift rename BookPlayerWidgets/Phone/{ => Recent/Deprecated}/RecentBooksWidgetView.swift (63%) create mode 100644 Shared/CoreData/Lightweight-Models/WidgetLibraryItem.swift diff --git a/BookPlayer.xcodeproj/project.pbxproj b/BookPlayer.xcodeproj/project.pbxproj index 8456e6232..f6539401d 100644 --- a/BookPlayer.xcodeproj/project.pbxproj +++ b/BookPlayer.xcodeproj/project.pbxproj @@ -383,6 +383,12 @@ 638E64CE2B8E1CFD00DCFA3B /* SyncTasksCountService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E64CD2B8E1CFD00DCFA3B /* SyncTasksCountService.swift */; }; 638E64CF2B8E1CFD00DCFA3B /* SyncTasksCountService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 638E64CD2B8E1CFD00DCFA3B /* SyncTasksCountService.swift */; }; 6397206F2CA71D600045A4DB /* .swift-format in Resources */ = {isa = PBXBuildFile; fileRef = 6397206E2CA71D600045A4DB /* .swift-format */; }; + 639720722CAAF8290045A4DB /* LastPlayedProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720712CAAF8290045A4DB /* LastPlayedProvider.swift */; }; + 639720742CAAFB010045A4DB /* WidgetLibraryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720732CAAFB010045A4DB /* WidgetLibraryItem.swift */; }; + 639720752CAAFB010045A4DB /* WidgetLibraryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720732CAAFB010045A4DB /* WidgetLibraryItem.swift */; }; + 639720832CAB0C380045A4DB /* LastPlayedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720822CAB0C380045A4DB /* LastPlayedView.swift */; }; + 639720852CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */; }; + 639720862CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */; }; 6399F94D2AA03C6C00A5C8EA /* BPSKANManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */; }; 639AC9892AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; 639AC98A2AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; @@ -1160,6 +1166,10 @@ 638E64CA2B8E086400DCFA3B /* RealmManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealmManager.swift; sourceTree = ""; }; 638E64CD2B8E1CFD00DCFA3B /* SyncTasksCountService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTasksCountService.swift; sourceTree = ""; }; 6397206E2CA71D600045A4DB /* .swift-format */ = {isa = PBXFileReference; lastKnownFileType = text; path = ".swift-format"; sourceTree = ""; }; + 639720712CAAF8290045A4DB /* LastPlayedProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedProvider.swift; sourceTree = ""; }; + 639720732CAAFB010045A4DB /* WidgetLibraryItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetLibraryItem.swift; sourceTree = ""; }; + 639720822CAB0C380045A4DB /* LastPlayedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedView.swift; sourceTree = ""; }; + 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentBooksProvider.swift; sourceTree = ""; }; 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPSKANManager.swift; sourceTree = ""; }; 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPDownloadURLSession.swift; sourceTree = ""; }; 639E12C52B85AACF00C875F7 /* SyncTasksObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTasksObject.swift; sourceTree = ""; }; @@ -2013,6 +2023,7 @@ 62793619272CD9800097837D /* Lightweight-Models */ = { isa = PBXGroup; children = ( + 639720732CAAFB010045A4DB /* WidgetLibraryItem.swift */, 9FB20EA429A281140021663B /* DownloadState.swift */, 41188D3026ED715D0017124E /* SimpleLibraryItem.swift */, 9FFCC08E289418CA00F4952E /* SimpleChapter.swift */, @@ -2220,6 +2231,33 @@ path = PerformanceTests; sourceTree = ""; }; + 639720702CAAF8180045A4DB /* LastPlayed */ = { + isa = PBXGroup; + children = ( + 417D9993256DE3FB00C3B753 /* LastPlayedWidgetView.swift */, + 639720822CAB0C380045A4DB /* LastPlayedView.swift */, + 639720712CAAF8290045A4DB /* LastPlayedProvider.swift */, + ); + path = LastPlayed; + sourceTree = ""; + }; + 639720772CAAFCAF0045A4DB /* Recent */ = { + isa = PBXGroup; + children = ( + 639720782CAAFCBB0045A4DB /* Deprecated */, + ); + path = Recent; + sourceTree = ""; + }; + 639720782CAAFCBB0045A4DB /* Deprecated */ = { + isa = PBXGroup; + children = ( + 41ADD6D92570AC6300660C64 /* RecentBooksWidgetView.swift */, + 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */, + ); + path = Deprecated; + sourceTree = ""; + }; 63B2303B2B8CCDDB00AEECED /* Realm */ = { isa = PBXGroup; children = ( @@ -2266,8 +2304,8 @@ 4106413E258725F1008EB8D0 /* TimeListened */, 637DAB092AEB3E0D006DC2D1 /* WidgetEntries.swift */, 418445C2258AE11E0072DD13 /* WidgetUtils.swift */, - 417D9993256DE3FB00C3B753 /* LastPlayedWidgetView.swift */, - 41ADD6D92570AC6300660C64 /* RecentBooksWidgetView.swift */, + 639720702CAAF8180045A4DB /* LastPlayed */, + 639720772CAAFCAF0045A4DB /* Recent */, ); path = Phone; sourceTree = ""; @@ -3377,6 +3415,7 @@ 41D20DB325D5F5A100AAEE30 /* MappingModel_v1_to_v2.xcmappingmodel in Sources */, 63C6C31A2B5E102200FFE0D8 /* SyncTask.swift in Sources */, 9F07B79929B770B7005A939D /* BPTaskUploadDelegate.swift in Sources */, + 639720752CAAFB010045A4DB /* WidgetLibraryItem.swift in Sources */, 63B230432B8CCE8700AEECED /* Realm+BookPlayer.swift in Sources */, 4124AB1825DFE07E0007C839 /* DataMigrationManager.swift in Sources */, 41C3394A25E04091003ED2B0 /* MappingModel_v2_to_v3.xcmappingmodel in Sources */, @@ -3435,7 +3474,10 @@ 630826162AF6CABD002ACE0D /* SharedIconWidgetEntry.swift in Sources */, 9FF383D52A40F97000BBAC11 /* MappingModel_v8_to_v9.xcmappingmodel in Sources */, 634E67462AFC7DEF00595BAC /* BookStartPlaybackIntent.swift in Sources */, + 639720832CAB0C380045A4DB /* LastPlayedView.swift in Sources */, + 639720852CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */, 630826072AF52831002ACE0D /* SharedWidget.swift in Sources */, + 639720722CAAF8290045A4DB /* LastPlayedProvider.swift in Sources */, 630826022AF295AE002ACE0D /* CornerView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3633,6 +3675,7 @@ 41188D2A26ED4D8E0017124E /* ItemListViewModel.swift in Sources */, C398559C20C492FF00BE9EC0 /* AddButton.swift in Sources */, 9F89D89C27EDFCA400F73947 /* SceneDelegate.swift in Sources */, + 639720862CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */, 9F3D0CE928C2BFC600E9E8A3 /* ButtonFreeCoordinator.swift in Sources */, 416AAC3323F51031005AD04F /* LocalizableButton.swift in Sources */, 63B50F052B692E4200BCABBA /* ListSyncRefreshService.swift in Sources */, @@ -3774,6 +3817,7 @@ 639E12C62B85AACF00C875F7 /* SyncTasksObject.swift in Sources */, 9F56C84D287B734C00EA9751 /* BPLogger.swift in Sources */, 418CABB425EF28FC00D8C878 /* MappingModel_v3_to_v4.xcmappingmodel in Sources */, + 639720742CAAFB010045A4DB /* WidgetLibraryItem.swift in Sources */, 41A1B121226F88C500EA0400 /* PlaybackRecord+CoreDataClass.swift in Sources */, 9F9F3B70280E4E4B004359DA /* SyncService.swift in Sources */, 41A1B104226E9DBA00EA0400 /* UIColor+BookPlayer.swift in Sources */, diff --git a/BookPlayer/Player/PlayerManager.swift b/BookPlayer/Player/PlayerManager.swift index 659c40795..24025033e 100755 --- a/BookPlayer/Player/PlayerManager.swift +++ b/BookPlayer/Player/PlayerManager.swift @@ -93,6 +93,8 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { private var playTask: Task<(), Error>? private var playerItem: AVPlayerItem? private var loadChapterTask: Task<(), Never>? + private let encoder = JSONEncoder() + private let decoder = JSONDecoder() @Published var currentItem: PlayableItem? @Published var currentSpeed: Float = 1.0 @@ -147,11 +149,14 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { isPlayingPublisher() .removeDuplicates() .sink { [weak self] isPlayingValue in - UserDefaults.sharedDefaults.set( - isPlayingValue, - forKey: Constants.UserDefaults.sharedWidgetIsPlaying - ) - self?.widgetReloadService.reloadWidget(.lastPlayedWidget) + if isPlayingValue { + UserDefaults.sharedDefaults.set( + self?.currentItem?.relativePath, + forKey: Constants.UserDefaults.sharedWidgetNowPlayingPath + ) + } else { + UserDefaults.sharedDefaults.removeObject(forKey: Constants.UserDefaults.sharedWidgetNowPlayingPath) + } }.store(in: &disposeBag) } @@ -317,6 +322,31 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { } loadChapterMetadata(item.currentChapter, autoplay: autoplay, forceRefreshURL: forceRefreshURL) + storeWidgetItem(item) + } + + func storeWidgetItem(_ item: PlayableItem) { + var widgetItems: [WidgetLibraryItem] = [ + WidgetLibraryItem( + relativePath: item.relativePath, + title: item.title, + details: item.author + ) + ] + + if let itemsData = UserDefaults.sharedDefaults.data(forKey: Constants.UserDefaults.sharedWidgetLastPlayedItems), + let items = try? decoder.decode([WidgetLibraryItem].self, from: itemsData) + { + widgetItems.append(contentsOf: items.filter({ $0.relativePath != item.relativePath })) + widgetItems = Array(widgetItems.prefix(10)) + } + + guard let data = try? encoder.encode(widgetItems) else { + return + } + + UserDefaults.sharedDefaults.set(data, forKey: Constants.UserDefaults.sharedWidgetLastPlayedItems) + widgetReloadService.reloadWidget(.lastPlayedWidget) } func loadChapterMetadata(_ chapter: PlayableChapter, autoplay: Bool? = nil, forceRefreshURL: Bool = false) { diff --git a/BookPlayer/Settings/Themes Screen/ThemeManager.swift b/BookPlayer/Settings/Themes Screen/ThemeManager.swift index 182677bec..ac37da7cb 100644 --- a/BookPlayer/Settings/Themes Screen/ThemeManager.swift +++ b/BookPlayer/Settings/Themes Screen/ThemeManager.swift @@ -15,6 +15,7 @@ final class ThemeManager: ThemeProvider { var libraryService: LibraryServiceProtocol! private var theme: SubscribableValue! + private let encoder = JSONEncoder() /// The current theme that is active var currentTheme: SimpleTheme { @@ -24,6 +25,10 @@ final class ThemeManager: ThemeProvider { set { self.setNewTheme(newValue) self.libraryService.setLibraryTheme(with: newValue) + + guard let themeData = try? encoder.encode(newValue) else { return } + + UserDefaults.sharedDefaults.set(themeData, forKey: Constants.UserDefaults.sharedWidgetTheme) } } @@ -57,13 +62,19 @@ final class ThemeManager: ThemeProvider { self.theme = SubscribableValue(value: defaultTheme) } - NotificationCenter.default.addObserver(self, selector: #selector(self.brightnessChanged(_:)), name: UIScreen.brightnessDidChangeNotification, object: nil) + NotificationCenter.default.addObserver( + self, + selector: #selector(self.brightnessChanged(_:)), + name: UIScreen.brightnessDidChangeNotification, + object: nil + ) } public class func getLocalThemes() -> [SimpleTheme] { guard let themesFile = Bundle.main.url(forResource: "Themes", withExtension: "json"), - let data = try? Data(contentsOf: themesFile, options: .mappedIfSafe), - let themes = try? JSONDecoder().decode([SimpleTheme].self, from: data) else { + let data = try? Data(contentsOf: themesFile, options: .mappedIfSafe), + let themes = try? JSONDecoder().decode([SimpleTheme].self, from: data) + else { return [] } @@ -92,11 +103,13 @@ final class ThemeManager: ThemeProvider { } let newTheme = SimpleTheme(with: newTheme, useDarkVariant: self.useDarkVariant) - UIView.transition(with: window, - duration: 0.3, - options: [.transitionCrossDissolve], - animations: { self.theme.value = newTheme }, - completion: nil) + UIView.transition( + with: window, + duration: 0.3, + options: [.transitionCrossDissolve], + animations: { self.theme.value = newTheme }, + completion: nil + ) } /// Subscribe to be notified when the theme changes. Handler will be diff --git a/BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/Contents.json b/BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/Contents.json new file mode 100644 index 000000000..00a3f792d --- /dev/null +++ b/BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "logo-nobackground.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "logo-nobackground@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "logo-nobackground@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/logo-nobackground.png b/BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/logo-nobackground.png new file mode 100644 index 0000000000000000000000000000000000000000..bbc5a0f83190c7291a947588051e8d8c19a96b90 GIT binary patch literal 9617 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Ⓢ#>9VW49u(}Z7Ko#;_PC=!B=hzE-Wwy1O!1~)fbfersjviCnhp)V^}`nV zYxU{PH*Oq^Z^(t0T3@F0qYM?#^J+F|-LwRMZBj=jNTm95yF;FOL3DoNm1hqA3_ph4n>rpU`O<+1gH3W722?n1&N~BSku?z+G*!hr zteQcxvyENVCU~nGxb9GaUpvZ1Zml^j9dx(cLH5I=&1`Bw5&^ENHx}ZtAZlV%+ijHl z zSX1j(pCH=UdS3Ww6a)jm+n@uY>$Q_f`8{7P(EUN}I}m|g1J?_J`yb`+*G6tF)+zLn@D^TFSD3OMt7UcNwX~}+YE5i8c;Xog)+Ow95#8cF17S6ZETbTVlS<1() zAKv6)G8By;VLkO4q1!G{_W4(%ozRWK&BL4?cEHyim*6nC*DJi!(ZPW(E0E9k;tE>A z$$8(JT6ZwJgQZ9wa`4lfD-U$}M2AZUUzNbf=^$(bA+?^IpuZ;3dFo^VUs)&gyy4QS zl8GV}ZH-MA`i)UJg+qE0CK>$s_Q`moN(j?2Bd+u-Dpzj7tVtLZuCxv##(JkEkYj5X zxc(_yhI|{96y+6@Lk&KXZG{Og6F(NPMD?5NN$8se;+&}@B|2ltCbWoI;h$X#(N1Fe zgi3={Ed?+eofBGFdcQ2pnPD4-KM4FNz@V&4RHOagbT26B5sZ69smM@)B;U#3jn_TU z+-A5!OxTs|Zn_z#o?ckb9aOjxM1l&N8CO1gPtmCiXW;{M1~md-z1WM9xA`|Ws^#&S*Y#{En-)+pOUG9u5O|D4onDQb2a z`c(zrkJ~IKYC?k1kaI1{#Lh#mrw6^`00q9NNUT9+liFXt>%Bqv`I3CK;f^}qyBGCqoG98a&7cHcqvlayJ_ET-?V1yb^n__%@98|T1BT0R- zQJxx|Eem=x8WaJOiEJ?@SFvoGdK!9m+lI{S0#h=brK{-0%{Fwrde+xE7K4sgD7h2KQ*AI;6JcOzo{bODSt3_>Wbz-bn*|ekPLzZUV~NQ4S+L@%2&~gH<$yFHa1^ zfc8`wV5>A%-XKcEmQ$d%*HME&2d9ts8r*}6jOA2=?|kkL`#J=IT`K&`ptMJ)N zG3zTh!7-V2%-%yNA zk=JdRoUmU0_5A|vGvi!2>b@_xqX&_wzoKJm-gq4A z&bP$53mk`OTsjv}?5$T0PYRUCZuh$VM!G$m>`D@ox_j`d{j^ReLp6Df403ksA1%pw z7ghDtlYxtZ_r%C=yP(potA*`Kp`6#MwcnT}Xh=)EBe}kA8AR??fQsm+HSVxzZlenc zcND@n_iW7#V*GuGrKN`5sspvT{21Ml&xtRd;V+~=OrFpymC-vU`cs>kw>Hi@0e)Ki zi!9N)9FsNe(T9A0ymQHwK`QoXXP?~ZR7@*Qs#?>&I}9J3!?O@qd@)eltWI0q0YwDY zeN_<%9CB}U67WAM?!Q^F?0cdrOI>BRs_PP$7&=cRhyCtLUnJ9M_{A6zA#qDXf+ABP z<7t%dR~Jj$&}dbTJ4Z)anQC(9dT@g#CcpEO?!Ms$q?q1z+%t}cac<(O6`9SH-LG8r qR-xe2%Kvp-;-5z<{+ye5Mlt&gv(!&eK=$X*k(`v0WTm*V|NjFuG3t*1 literal 0 HcmV?d00001 diff --git a/BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/logo-nobackground@2x.png b/BookPlayerWidgets/Assets.xcassets/logo-nobackground.imageset/logo-nobackground@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..df799f802456e649ed06318e466ad2b1b677749c GIT binary patch literal 21234 zcmd42bC_klwl`X~ZM)01ZQE6=Y}>ZkW!tuGyUXlim%4Q8-TT~g_C3${{eS0tvNGn# z_>GaQBy%PiNu;8@1Uw853=j|yyp*J<@^?J`Pk@5>{;koh&HawR%!TBHfPfm}Vc(6w zzn_UrB$efWfV?PxfC55*fc}270?vSdTp59YE)0QyxHEu&Fdcq&D)D|NcmOn|%;e;N zXufGEATVGQAkc3L`1=L|#sT_A+cyQo4~+ZYw0O8B5ZHh5<-g;9F3IokkKDgw(0t(k z(UK4H-_qmxp#MYv19KTkCi#w_9VE4!fq-C9{|UfASwFFWfI!kLRW)5S}~0d zOzn*U^d7bj|Db?)J-EL~TY!rZk%z5~oin!wAIZNYxWDOt*bF2@{}OSr<|EORQzR0x zcLETx(=*aDlJLV25fSk^nVNAci;Djj{QHTI#KOhJft!KB-QAtuorT`s$((_Si;Iha zk(q&+neJPH&e_w>#mIxs&YASzO8#Fxq5x+TCrbwxOM5$_fAks|+q=5(k&ygj=)bRj z=hMZ~?0+oTIsaF&z6;3kPYMGQJtM>a2?p@6{J+5dN%=SIU*-C@Io^Miace09ob7E~ z|H&3V2Q%-#Ec}0%|C7Ie12q3nfd6FvZ-9c6CE)un`IiNz|1$8Oy#J8@C!gGkmL32b zO;Jl*fSvO{xng2uX60r0KPLTesEECdy_1TAkqLnR+tR-v|H1m-(*H7~^?x_?A4&fO z|J~;JVH)lkzPpwnkd&y9st54z9_Ro)u~ZIydjoH| zP7z8lR3sAUsz@kcIS{C*Ut#A9nSHoAxr{;Ami= zfJN5DphI#D143LVb9VLnK6<`xG+Zwqf6Mpz-RwTwB_FHb|Fu&qlmD3IQY%Z-(SYJ; zhx-5beYFGS@nrXezrQ;&jI8;LQaEC~u(aaZw>M2+=eg%&@6Wx5j~cu189nhy_NA;< z0c9rA{=4;U=;hnzz z0k{jqApw25H)3p^`L_myF%+l&)FUGP{v!lC28^c?6-F`;F;wEIlC{@CL#ZGMQ~ksZ zywB0Y6lS;Z$VTgL4$pRM)fiujdE1LK&ZRN+`;$vTu4NtCcZQflJ(0-I7*+rHTj2QS zwZm91UVUJ1u7jXDg6HZ{hdkgyVWDpH+#8j64qK~abYUeAj4%$ZnU`B88l{G|7PQ%%*`3?rqZ)5jsAIn(T1JY>#bI=@#ncDmGq%xQ4DZF{jFzI zE)`88Ys3AE6J_H&&X6y7wDd6+Ta*g*J^w>D6~eQJ5=X!Cyk7bU4NYAj1e$aSidNqo zVW79;Dczdw%jpBXo<|Fk-kWG&2%WKcnZ#4gcNMl+!h8VH5Qv*b`ITdcXUkV z%mfr3Dv3{P7~If}-P1HerUmrZ>1|0FNefl$b*a0xvsLNoi9s3G_+RTLnoH>JaS&pg zi$4s_g#;xIsbrcW0Ld;#E#}`}rT2flMBjSN4Mxo3sy3Hs%+6daFtU8`-TjpAda9HQ zoUQfDBs6&FpZ>Y#Z!XgPYLOCI1EDw87zH~t9vX}+0C(QO@g~n%ST)6BXAt9?ESD{5 zZ8?h<{`_5X?Rm{iKs%)|TUuGqs9^azSnlV;3CEg0XwVz$k$#BvA6D*+zQ+?-cLTrI zq&64eE>pQZy|WALq(eR$=+Hlhsfew|u%DQ|{Ql1Tc}4Y8G~q(gyBh2$k>JS{qIq*a z_}ymjLlMi>ZJ5sD>lnp1+dlGXVqN>~r0gDD5g8y*`oy)ek|snUd~bk&s*6Fv4UfUq zsl2c2ozwdIBupj-sqr?2{7sv0y!X1k0*w2=fam#9kK#eDTui^-60j*h2;1GUZWSAS zwgxJK0;PYc3JtzeP1allG1o$eWpQ8IS=s2Y^701s7DI|85>xpLktGLr{bKn*fO$8N z+rQ=ObnZc8TjwoumM8D{9gZ6}jmfJZGA^mmRZ&jV8ITzufK}Xb1k=Hg*Y_Uce+qic zO+~tl{G3vh$pL5Wzj2DV8xhEzI0N8x(Mzo=XChhUx4$cA&~0`oVum5k&Dm1XwQgR% z+WJ$bOgN4?yf*|j7a@wHy?myj9fTLl9`zZR3%U5QC4YHwF>R4~O|6-FXhQN_sGHTc z|4FiXAF60F<|!v<8~yjqJFKAWPbOcc3(QR0?aN1CnjzIa;)d*BLN|CygZ96jkJjA; zcXlI~ORlArUG1;Fn&5 zpL_vTglE|vVHPS(s3=7;TE+eV?PBBKf~%+mt=5VT+Xce~Z-QET6yb?x5>R{Rke)%o zT;EnmI@aLRW*2Vg_E16?*k_=&1&DiMidLtW1po{fNC8*I(O)wsk6VM<-lqX?rm(l< z`Z|vrr*_DJfI47gQD!#TyyzN9wE+vqcJ&{5SOips2KUE0wf--+^a{-9 z%|5RMcoe={pq}So3{}0}3dtOJZ?3$X%~&7somsSvecFeHLQqVTx@2a;rZ^t<DnhE?l@shO@r4gRI-gj35_ph#2Jxt7%Oz%U3 zZjTp=8EM$Yg!AJ7CJm!RF@Wej%Gu&eAr6y`#@AmnSUjzQ_54cFxoTCpf0lZRe`HQ! z`r}5k&kPTnLrl`>Y+F49@{`hR)4Wt;9nW}+&ad&X)>GiZ+t8oDoQ9La*Te)9I}ZPl zJ{*FEFTzXU8lOenua|Jcel+V?-bZl2N$ZwB~3w6a6Hwo7>X{oNA{6 z>p`6PA%D6P;Y3HzWbY!0@O^~FoyYF3o)Z!0A!BSx%~{nnc%dzjbWa8dG_k2^hTW=4iK?kX}oztzgvJ z@uH>>@^OJ&7zG!uFEzDV5WujSuWodtwJ7udp5TZsq?8vEFW;>%krBeAO~%F9PF0{l z2@DLZb|+f+AuLp9VGAAo)Y@)g1s82N&yX4v2EtE{i`qgvkANdFdie+r8u*Jr-Jow@ zC*sTYehL`eO`IG#{ELwR&U&i5e~1HgV7||+30r8lUqLY)z{~!JC2i@{w1518*9gI4Zbd1~~s!SE_FL-C3OT94X-RZkTsN7B%;#`+|mgY)2dA z0_sPmoUIHWK0Ik-uOa`Bt_fRDiWR{aa)eL-?6PbvwkX%1wv!D(Yu+>HmcFL>`${SY zNu)5+)xz{xFI(;Y8`#1kA=rWiO?W@3)x5a^cf_Io@sjb==!2STqXyfzdW#5fLnL>6Wix+Xent09d znx|sLJmudxkLK4Ukx2g5Q1E3EK&%KZgdSB|>@gmmbaW06Dr1Zht>W|n|GOqHVz`gy zd?Y)y#vc$7lhz%WbY}X|BVr&I1lSE-p6l+YR~oGaB?dQq+V1n~^qwA(OcFRqXX>sw z6TJXtX8OlLr)zdp*{r|}Shqt^9Yh8XpBe)Dg1O|!-&b1Ot2@Vu571pJ?UAi(XFR71 zKk^PntaOMQyH+??QgR0A`-!M5Q2I&4Du4z88e7OZ*%ef4C zYy<;SC8*LMB`K%6uMl1!&qgUu(^CB6hZp0sS#d?o4NdLenl6$mC3EFUZEo0nX~iYv z0rLEW@SG#WyD*{Lu)k%cA%y-(%aNs~3Itc7s(y8$5S5!7Vnf%6bqWQ9+FA=|BN>Ul zBzcj-S#0KHia@`%$M|7DR}vbne4BUEX4|3@~9d`STb&f1hP(przi!7P$D`P z7qZ^KLLJrs7Y!&gs{a~jta2$~p78z*P?+Yo!a2#E?`(|S?73nNOo5$)+hELk_vGEM zsAftaIQzI->ur4zFg1PGdi~YPZa?c>KW4y-XL(Xk;DL!UCtiqfy8zY8bq`VC@d*ig z#P5DBWgDzr#tL5+2Z++_yXsU#b*Wet+OD_T`jAs8rMuqi(1Qv2q^Ci9f4}wrK+460 z$->-FMQKs1B?Pji#(>EVZWtHY`h354G-mW~oy(pvSzjG{bWZa83?!n0rBn4yDM^^q zx*TYeHyb&L-DxDpmS~U(U6mHbgd-JFw#>o_HrCdGtC3L^CDFZ=Hd(~?2I!K56lNfR z4HEa7gADi)(61>B;OpP%g}a)NIzy4(RSBph`$sEnc}2C=Zr^Gt{rOxzMeHwEVMI`v z_(-h5AJ5|1mP+Y!U#nk_TP-96)v1Piw}4mO6H!Ar<|Hn);W8uKpbw(*4=nNrOYFxL zGMOYbO81A`sK1Ob+V`Q42jtTgc$eX`T`FYmPy58rvA~L&d3ArL8FGU7S^7Af-g6xd z5UvI;u=fMGNC>*G>b19lF4leRR-Okj@5cK}fAtwM$iHCLOcM)VX%ZhJO5iD3 zB1!_PTD@`)L9$4-CB7RI(jK0 z(;w70#K%~!9Zk@TajvT08sf)oB%Xh-fr@3nnrI6GU(AYxLs-Em0Fg%c2%Umk!w5$O zKfP!XtI|&wN}6*x5GcEU`#k+b;Q6kbC{0m~M0N=Ql(fgqql~Y=N*(2n|q0f#c!|8#*|G_5Ixi9yksd{A;0QsR*n9 zYqZGnL~iGeNi_du+fASy8e>V?j?eTOYm7cPIKyEiL$py}<}$$WW&%3aU!UEhc|$)3 z4aA=zyxo+RdOos?l_sX^P_;9Gj;4ew^Cep?cA2CrZ$8b1tJ&OEfpQvB5mfmIs}^V} zwKz1Ul)$8Z&7ig8CutzEusxL2*v)Xw`4GP>7<|Rzr@ME(1ml(;!Y`er(56`@T^hJ+k#bFuBz>$VjQM<;p7cXdE zUEmHoNIU3spY2Q6Tkd^@R=TqjE!OTAQ&KCB2rn2}d} z49#%5KN|A*CF7RgSJ|x|{pTbpsrm^JPk87*A%>oJV%TCaD%XCf&ghGa z$ou<#ki;2EOO0r$=$>f2O9gEToenx19<8Z)TNhliC0S0qh+Y1Zk8|Z%ue) z7wO{p@KRNs-dEym-R#>^rCQZ3x4p*3nrBCTe9ql00G7E;|7%Oywe!^D-j}q zBpL+H6bl07fECKLupx;vDXcWS{l#7t1;X)Fvqdn49AHJM7+x+TJ0%ok9bYRAQWB0l&kMkf9lwP! z{S7H~SZlRZuIaMI2~rswE`bw=2Q2)=nM#L^pnT_HdOLJBt_Lx=*Ii;@;~887LrGl3 zIT^>t{ksBgHPR^4_j6!njo)SVbxOV)9`I*6hbKLoIHrV0kdHUkOq|CYr8z zWhFBn^VD9%02QGw4gwejtcbCA!riYRN2+$rs41gm$zlUp%T$)9fzeS1_K;Nng|Je> zud~kZ6Txu}BFo&GiAKQG`UXZ7y=Lf|G0!m<&*7csA^Q0rM%{83H$x)yBe>_;U9_~9 zqLzThMaH0Cp#al_t6RjW;JpaodN!<%wBuB%7YS?-)FmuU3j3wj8|ovvdB(Ju*gAT5-xupl(N6BA-X25^Lgv zvF7eKXA@Oi(fa`x4n-K@-k4&2QGuh9Z3+Yfl&>rFNpA5LJe}2@5sOF;1&%9oQcFIw z*7&1CiUL(90 zc=!lz>07YKJPnyg6`8 z8=sRAIBgOE3I--X@tNWVp!dAHA}>D%>neqD@txV=mGsVW&;vj~nboZ}sEEpd>G<<) zI^3roy-?QEj>*9(lTH(BsogR2N&5YFqvVLNiv+yswRVY0hp}U&02a&%i=}a~_Kj60 zSQLsP4F@neI8WfYjT_t)pbT8LmDPG$Jgz)*o0UHq-&_+hHmt>;SmU<$PMzfCZ!6{! zOPNAupUEi;?%MX#RafTPQ2f{LxvsyWW0yMarHK;bV=wJ_vL^K)82tttejv=G{cc9a zpQvGpF_bav*COAe;r1hm&MusON78urrZX|ho`_yer0B>pl2IA$vC(L~c<(rz2s5Mu zc;{DEaY!yOG2aSqM&@i+_6ceDDtT@i5|*^_1UcJFGKkw?9Yy%U z3!p}a1v(~Zn8gv0e7whcd?FP~qE={48BX=kX5r*0f(+BXK!Ivn1pA$p^vAykPB#@b zU15#HSdf%^SQ%+W)}4RMHcygF5b+Pk@~@;$-q^L0wo1TaQIzg`PA#mY2j2efS$O2 zU&}~F|KhqiKcz_vwo9JP&m!eA6>4r#Pd1aq`+i}iidHWMAqb_nTNKD8>hXqo`7+e3 zoUlL8qxD!p#x~$6lk>4PYXXk$3WYN8vQos=gAK<>_2#@8p&9%ii?uYghmj}g!ac3~ z6NBM&Lo9w^ajPy;>xfn=uu>1+qCF^0B*`g0c43)VFIPrcvP(;k!nY6`j?P2;Od*Dk zsV%87JVOd=N|E0nQT8pAVnR}lQd$2wnKfp-CCh6%V~?r;9-0zWsKUo?H|>a|*qF}< zCx=fdKcXWk&%H{W;WAE|uQD6{jdNkhmJw@+f;ngsF&}Gp$(>d%4L7uD5zdR15LL_dUbk)E)1U6jj=TdY7na20S~7hIJJ+ixi}nbjWiGK{7lo35e6&jHDqN=n=? z0kHOb{FXL0TmI!lRlp8pb*Uj-R4ktu?%KknOx#ig!R&r#465GJ6oyycT=-Kwwm_Vh zCdIUHEMG+Obq}76gve-^P{r0R+_++~Nm#-&Qk!T9t(oUbpt zx{CsLsZEn@k~RvHVInhE8que15mVC9r-#ZDHP;Cxk-&U=%Gmmte^ll&aaNrDoZ2E^ zZww;=54N>0gZ8U|ed6)UE3BGCr-)RN@%JxFk|BU$Ga|=w7*MK;+p;w=DAzg*k|_*+ zA^kwFX`lL~Cf${6%Bm7*$GtRw=xnZ3vBj$_`xKi_=CRFl4_LpVv6jh%O&d{(kM&Xo zN+t|t91ax5npCQ2ThtBF7OZ%(J_}wecKz5Be@^AM?y1CAv`a}Q?+Y{)EBq$;l1?;) zx)Ehr!7?R|@!S!8#hd&I^ zZu&XCO*6x7SfNWxYC?Bu^#X*jOx~_ee1Va4i)*jERw-r27H5J{{-am(5JCP-G)4&) z*I4{b1hgS>5l$T6)QUo5&G{Z9+H+(HH`#dB$nmbq06!f6H)cc}sPMr|4fd5apoYAF ziOW)v%|wbkojz?9MaE&$NWVA&t5fX_>J)5)XDtXTv-GY*Wq+c=_NC$ogUQH6%S2W& zqLN^RcBRs(0WFeNDG?XP$M|=akmKV@(?}?0ufcFb3+2$ki1RQ zu>@vppi2h`a9&46U&C@li7IFpYr^`ic#v|Nsb$XFp(d=;ikb#8Wa2%1m$_z&xNx~?m<7j||Tk64ck~%|u znrr1UN@l|2up>?=Ic3@M-DCu9gtX)NBbb?IR<``fXco#faK>ud2&m~hEgH5dQf_+7 zHKNf~ZP#aAMrHHf$w1lp2?c;Qk+vB-O`>-N#CV&pK@Sk!8_DmZ`)s9#d=JM0Mis11 z?fB}O=~P%F!T_FdJB=zKl}nr!L>kf*FhVT_Wz}>xzeC1|d$=Xr5XdUUU4tTMVV-9X zAg%mfqlFybem{(Gozkjm7L=aqcb+g-7SgFewBp&&nax5)PSNX-o%DI9X*OHLwV#i& z3?n}r9JH(%k}26$+m`AMd1CWdE2@&T2t{y{CGThBD7R%?rm8o#qPaJ-(vsKEH!|ei z4?wH4gt6<=RS> zoj7IB$$2`vkL>DsGFiLHHn%tq3HgChQI;y$W31^v5Ig=+f`4&Rmu}T;>Ck}yC8w2> z)#L)lR`+Th7Yv7cyOrE&Osb1*pT&+aT0Rfj3qM&NeIr7FIL^f8Z+09LXNncqDyqYXqtR9b@g)@Y)13IkHGo{_53P=&R8+MK#_m;{k`wG=$NQ#WM5=#km6ZQ?U9xlSly>&yp zKqd+<0l(N!ALd?mh};+4wqvY##Z2$*uYeJ2`-kWUhIRwqyJ71jit|Ou%`M!K=RSWL zH@~rRjHmTN88Zf~b7{@ZGLk8T4H|5n;^0Q*vT_{^745j|jKJw{*Ir@f80O>vy7>|v zlevD7ViB)u@8W@nRV<>6Y&>da4JglHq^N%Pr?~w4XIoh$YMg*54#XCuN8Vv^qgyoD z3pj0@W=q@K$eVnx1n<*&RTBI8k|aXz4u!hDe^UEpZt?cUf;Iv-I~(e$Yrs6MN>jC~ zJSslC-aSqy`FEd48NFs1gAv=Mxd^wEsHjKJQt-j;YzJ7aF&-AXNN6@H$`1BhR*4&QMidk+Ur6YkXb~ z@$O?Sf+gO&hb2A^!UP&6gj61>37qA*u;)nkQ1HPI%unP865o=26aKG1Wtb6SH`e_e zVor-INu8sR7{Yq>qNB>K8213xi-ZI0+Q?FMMd$lFKlpId>! z)4-BlQZs-mNO+bW=-G`^i-5)6Kg!a0J`SqYp9|q5)mkbgjt=n$Uf7V&Prjd_WMR>e zx2e=@)RL`96WtbeFym>LS=OIq0wbdgMhh!e{oxV}9Ug(2?govlm;6FXqyDOpwD9DF zd43~Z7EA>y%XH!^o$5@Pu~2c?P#DrwZoK?H5(-ZxR|8S1m9-7qFDbtgu(zgqM2j|2 zVR|bj7(P24HEDSZw6<@D5U2LlX((fh2m&ESX~I#14Yb|rU-G`V^l=Vg8SYUXSOpP# zgL6@xPsK;r)@;z-KTj+(YuKls@!acQPB;)z=J@IkbZP^NWv!?q_tiJjq1o%hloO`=Q~Brde~tTo;O(9EZ&KD) zc{zOKzl>}BKJeaqOUPg*r?3V2PAj0R>vM;4ml%&nSNl4E zeK5_kIWlUVwAf-&#K)R~X`YLY`SoP)A6m8c176i{9d&M&{|)M{jpP1TENVL7-s#>g zmbpY;sqLp}Vl)06&_Q(%-25_*92~D^I@E`EZKIk%-g)`lBMY9Ab6YdmQQ;7SKBJ1y zn}NcZ@}s10?2u}d?H268%b~fH&C+?b#i%<{SEoFtxsL^nE|1?6Jn7|P2JZ`=i~P3Z zm;pf7Z#&s&w;TIlkijj2PBTh4xCx`$#IlqDVA-+3tTKPfd!L5SmO!&`SCD!2l|{k)6}p+3gN|auxX7r7PT#=$bI~ctAs%vFnSRipt$+;R=`+=c5F6R4J{!&%)1#BX@WP4I|h+jxF{+Ru+L@Y~<< z4Ps%V2dYy-VJ}b2Z#-iJs6sz(DXDr5=;e=yfF4eCr`&6^NNZn49}ZGR7z0d&y1zma zURLT1Pzk?YmB3I+!z(ey zTda^toav6|lYpO|W%D=pEf#v;+53{}zL#$MiAF{UNBD7;cyP-l1owJ?Bg@7CIc)FG zLYC|Am+d33k9{(iN38Ef%+Lp~a9ByBifwDG-GW*XZznfhatLuSF*H($Xm4HdHaxB4 zt*u3*yV2Cd!C*EQCCw4}r{gT1&AEh72W~X88Ykn`!4q1d3Ssb#gk$%Qq-Ae#jfjLq z6X(~q$Vd;O!|KnEg2IefgglS?2@WzFCo359CUXV!n_R*a`yUtH%!48RG$vd|_u7Qg zdO;>XT&vWLQOn%71&=oE?hQ>UydxhcQXuc|1<%D(0L&~5sqK}h@>LEeJ|}_1jyscW z!$q3@Bl$Xsp|IwW*pT@}as05c=Lx~V2a%NC^QYsICT82zXHDI2JMe{V3_sQ^)V3lR zZRH9uG+XHJdVs@&4 zf|Nrq%h@C`Uxp?>wfMYWBc}BxOqknP6deR+GM8sLk#f4%xxODT{cIpLX(gh4=3fa~ z2llmJQs)6wi{P{(EZy;s?>xIibL?%CQ#ZyB810$FWzw|TO-ZfA7ilnbC!y}_1dHQ= z-^O6a8c$h!av5=2(nZj_(=qR2Y9rb6+b<)tC)DRD4+%ImCw@pC@V&)+z|u2$zBj<> z*X>Ye0xtU*z16GMdqGbvte`0MS%-IZMD8;Q-Yv3eo&(dKD=$P=fTvKPMMfb+)Cg2B zkasGXGh;2{x-{86oRT#~16uf3AI4Sfdp9WKy~u1QQ!*mNmwDk=tfZ5XK0d5WxbZ15 zR8T{ccfB-ePq&bLQQ*L~jC=6Ox90AP?>UUze9i5hR3|FlXJV~T5+IObjfoEp#YY!v z#E8cEqrLDo_i)8b5xW(+TQJ=h4SepTw8FZ>hq~=D;J`R5OHMgl{B+F$ZYxZJZ8~^_ zsDpwOE#L)WYgo;8mU>l*+wBvS1>o2m2G6CSP^L|~=RBS2a%IlGE z^y?+l%;uFR-)GOck1sK!z_Cw&mRv zj{9|Pw-XbnSRcAX50Kwp)i)6q-Ta0Ru-IAbJOP`F!u9Q7Y2pc>_<&5jDlL6^#Vb&yZNx`Ae9j^_dB_3|`lPEiF;jlPNT zD~vwXrAoBsnlcU-ian2U*P}5oq?H<1%9b>=yWPH8oyg7Sd06n%0*{Xm+i@9L>8@iA zpK@clW(=00o4nV5$L#Lf`s8{%%dsSy9uP#P%F5PCgTjc#!>Jhyvky$}FlC4^M zG_A2Xfm638$3Z5NPKKPdgy*9 z%5Xk@p}=QCgCQ?zMCH?)k0bO)I^n}X7|Qpw+V<_K`(>eWNv5mJK?TAt;Un+sHH9-D z{*myYF@7=p_{!Xelb)lFRBtEJ|9;LsO62sHt6qv810Qwz&G^TpX56srFWC!}XKV*Q zn1MSCFcU|Z0v!DeWzZBh5Ivz%7dqy3-Od&^qE&mW;p@w}3Am1Z?UMA8m+kk#6axO5 z#KXo3E-Nv8Y`@nj#K~A(m*{@)=k1T`m!~!Z%y0sn(aToPj-d(P7sj(O0sbkE9d+O0 zvNm_gZTCHPrZ;?{*Ie(FYc+7%36T=TWLcR`(=+vwX)BLwP1yT@ffNm$jvb5;<*H!8 z$`Ptmnh29Pm}q;wS2XP;ep<}2Qh28t6snZ{;K5Z=i7^76sRcRQbuS0^CkXy&mL*@~ec#S}kI6Mw9d8H9Ckfp1N}~-}43*t$rvIy)0^~(PHo;*Lfi!$A?Od z;fHK}!Bzn6&~U=;(;{>oCX{(`5>lK+i*K z;mRlowm;=v>I{lw8mo6GN+%=f2`6|MLhyQ>e0R_&;6d;Qjdi`W5Rl9V_fraC)~G4= zFDuUBsA<7D=g)Y!{ox+$QYELQjtt%Pa=K3~Z>9z&o6Y$)d|2r^U~C+3!y9>ugqHyKpCaIgxx{fT8TG9Xq8G_qnvtwc$Q(=+C?-kNMT6DDSD(_Au2 zL%o`Sa_v4_Jv^ViZ2DLj+l^UxdS{d)zCDJLs>O!B1{i z%1&!;-9(SLceC#7QQn{Jde>`PyLMNmApE#E@AsqyeecKK!_%26hMJR{7KVK5A!h=R`x-U?(Y}RL(Qm_EQVYL`tXAdprMD zyn@a0SLO8zI2G#*O|(DfU=4*W?7UPz=-vP3YbEj`4Q1Ze>Yc%`I|&rJ8_lM^i{@#K zDitTB0Q(R(5cW+E;Stey+iGzi_IZidwpta%Xd{3=})_B2|Qj0(Vlgt1=d{? zX&WWxxk&r|#!sU^RCm~zOopJy={d(A^i{%cd1{FHx{x()?!{wYk`^88OT68Bp6*4} z=&W#XPm{_Osc7{X^V>+ZBM%WnhL=nwO;E*e=|<2pB86T`SUGf>v* ze1vJav~1DL`OH%b*<}YPVGWa^l96RD()2#7?l(YAP@tq*WHS#JR9aH! zWkXI~iJ8;RUe;_JUtR-6_OM5BDvTU=U;EIrIiB;62k^kbt@l>lrxNI(!+jpf2>U|E z`A1X~%x|&Jl8-+%ZF*b;&ied6L)xEvf&a*~HxHjod*auVL3bsU&?}YI*F^4{)NH}0 zd+j((3!XgDrdcV%y(mT$Zi3B~nyCr|su5sx4N@sM9#Fm?p!Ugdq8g;*6U;`=`8>Hh zL8XZ+5APPR7f@wWpF0XCjNXqyCLg$ec{l2M6~c#O*{$C;YP#(^FM=N-G4i_rek_Ad zA!lk=(8qR$`yyW?N|Z zY9r#PnU|6@=3iC86_D>AnQ&eq=e->19WeNBkm#Ubl8PeeoB@Tqk__dv@0 zoer*n)TxhV&|=_su@a4&*P@-3bit54wSxcAj!A}@D(4DgBodbur8e}Svm)3GV))#An~uQm1-%FZ zjAHp32eeJLMCbW0u9oA2T=cN_E{jg5t_`0B-p&r_0U<*l=9J1ZN^13jMni5*pdLOE z9^KLfQv#FPr>97pB3y~}>XZsss0l=)<+-v}T2Nbmoa%s8)AY+SK8Tb?z_3*kEKjJt zO8$K#=#19yLk!X3!BGDc87{k1^sOOwzGIuvh{GFTi4rfW9kEpH& z8lunwBLv{0+Df$xHbW_DNv$BrG=s_YLQ{A>8mxa-RW?TK3td`-*^q5tr*EK70wm#w zG-1Z0u+<_MNmMM`(2du=m>y2cQR4~UJY;`*T?Avns2lhi|4^BgtlVdhkMoj=Ml?v1 z{?!#~WiBQUVK;(l*Y|g&Yj`v^*!YR|DYR0@L#yHssiu0A*5~UPMzK$~V;N-ezqIy%>f971AmJ-W*dxUVI-3eb`#&B=(ha`r7w+Rqu zW{pcq>!vqg^o|XzQYTVH+~|MgYktkkXokG}e3{g^Mw#Q~30ZR(A_=@fXO7vSRB33n>uKR2OZWgknW$#jtGG zHTQ26^0`n^C?w58KF#e?q^Wm{W$jS1c@VxVj|(8RTnx=-rz6VUV1?4SinEQW zIwFqxYc3VPuf5xDx*L1c!|YbXrT}U0`|-0$d73kMGsq{e2eFl;jV~WV(2W>uVq$RM zVbV&?Qi^)t%h94ZcDP7~F1?DzA(6&(^{8PsgsUV4Jw}C26nu#_TO+HT6C}LoF$W_f zQBcN43tlsv0~x`nb!6IvB%cY*;u33(iX#QMO+cPiY2x>SMl@p*t=aA#!+~S%_3)Zy z!^EFCzo%x-yW)iR(QxL>`|7i_kT>1)fd=lg`!l#1PIY4om&wJ{YVrvz%Z=iJkY&2E zU=y0)eVMbCGLM~)?Cjv&TN!d5>X+c^&oD{@GP4-5KW;{}x$|i0@YCz@h zp&$#S7D+wfmPmWfZt6ATmB5?^a#}qdCwJ+JN^Yeo=`=dce&OQOAZ;zH!A`La)IRKS z!i=C;8p{rCYK4YO^{%@*@)|0 zz0M3_K@cR^t;VTA8;02Q6$iaY_-IVRL6+9%_Uz)`>^ij@ifLCUu}ozQv8hP?SBmf# zn5JARrG9hB~G5#1|;8QM4BLRf#!`6W{*r4r}ctA?-Xe&`3S0dBBR5v5Ro?q!q8}{^HHKD5f)Xn}f5W_+V}ZzM8dyzD(&Z-v ztLK?qB3@O>GTK&|x_nfnPs;J`)oJdUwwyOn+m2QC8MS1 zc%?vN`F9*uxMhcF*%XhzQM|>VihKH}kiIchW;4CS3~};S_B;LpaW@K3juXFZRA7GZ zK${veP)tsLjZ-;Snl+wT>BG^&$$A%lZcS;y;t}i!h`;hzHA+VH%kX?m#fXpEkKr9^ z+sfQTcd0Vk6MME!IrrMy%KYFDguuSTTkF9M95dUC%b38y0LXbM>s~W#n0%2 zD$e)2pU+S2f_Q<%Un@bR0IiE+9lGL_yp)o|AD$CgLlBMf7=#AAI8#G;mNK5HTufEGwyCL9dad-ePRW29|-cWW6dKAGsVwO zOmmTja5D30Qv>G@s+knNeaT8?s*|p(P?|Bn*PYz&3*5Vd6S^MOD+0I!x2i!a!$Rd6 zuYv`&Jmg0j(G%q3^0uUH_!7;MLjgoLJ_4#Z5Cns%gEC6nxs-YQNDiyOP(N(J<3ZkO@gh$ph08yf;K`&>{Z1~| zYK!SacbDoZWxr3hMf3{g)iSN+7Vy}SS`PJQAu)d>2LUx;MdL12O4oCb0*7Hvj!p~_T}Q*Lq$BbYBtzf(el*z zT2ZA+b^m&Jv%u3)ukjN0lLSAF|FT&@m4Fm^?NZ2cTmSichllxlB_!}VH^dz3rbeOx zvaXu3Ul1WIX@miCv%X7NMy%JxvSt5PzedPda&O*n)sdUBeX%z8s|!uyF=vBUA~+ohDy;TweG3 zQyMZmHH;`0sJVeS(k0YmW|me5hK8}p))GD%bn~#Vgi9ML)aNzKL#Ez8|GAfg<2P^B zrGz(%6J#_rM93dfail{ZwLreGU5 zTxdNZ26|iz%|lWxE}R$v{7`|;D09XuCETXNXqvll1Zx;sDXM&i;ZZ?MoJ;56QhVHR zxkDKDD6Bs!cgk&~4}*y{epSNalZgbpsQuY7gGUlq$M!I8a!r$%TZIk3MV`|Vt@KFB zn#TiC7S1spI+XwVaK(@1p&IzRQfJOp zrk*0EyTo8+l(u$fpnIzV`(l?z6#%3+Smwf=>nW z+;4jfVsXcW7x<~qB)%x74Np1&b&s02CNEQGe$q^-(vmx@3O0wby8OWm-@O>X3@klq zw4_e5YX9Dy)Jq>KtY{657Jb+?)|YXXl(mkJTum#F2-#=bC-|$tbp?8c7+Pp-;qeQXG43Ye`$+BE2V=-in%(!i z#MPBow)j+YaEQNE>vR;100xmJ&c8og6Mdg zW5f%p9X>=&;u~6?!$fmS&U%!Uzvb4JoTl=l>gx#@piC*~1MO7hoT;DEpunxltthY3 z)Y5a&^Ta-DWINwGgD$SsO2XxTVvV>3v4R)0eiA?8uG;!iq1bD4@-F8AA6aPx(KM9^ zvK#Zv;Ojt&5*;Oj5M--jh^9lp2#Oiz*8`?NW2K(qqgh)&?+QyxV5_ykT45^d1VIx; zs$|P8@3y~p=9V1XvD2?>o%{mcrf5b}`onNwK_`5lJUy-P#1}Qm^yi^JfFMUnsx3t$Lq>Sl7#Po&s_{1>K+8($hkR& z*zPqrK8&Q070q~*F^b^e;L9$s9Wb!Ad>(r+j*6(}v_Yr-ipy9o%espui|}aQ?r`@9 z6?>`Lwh@%CUK~)7Q!GWz^q&Q+MrGlF!QDKtJ2&SV`p&lp@k3xA9IqoI(Cs;fw?civW>GOCGvf?9v8;B@| z!?2Kl82>-bocA{y0N2Ou7_nD`+7wOI7F+EtW>LGeMwO5nMTkx9S*s~E+S;lp5i4TP zQj{ufTC;ZT@p#UA&U@ZJ;l2OC{o$T-&%NKzM`tU6uR*W^my6QT8u{%^e9|4kal%4y zdo3j_^~6ziV5+vN0x{4Y%K>X)0Z1w7UO_iqT_(JqF{1T%Hln6j-AhCU;8l6wU+TVE zp&H0brMV(%5A2CITxZ+m>#nezXJ2OUqU0H(Bv!1`C|lhGhd~*7t^1C)`2Ia+1ii80qNMiRz^I}zLY)RA_i|XG7S1ZV5uSH;&MT@Xo zKeL)&DgBc2XN`D6$-8JJG4;&m`Q_PLi}yGl>+im;L`3v*|8)U?T}O9Fd}__p@A{7o zs728pEy0~%u0h{07M}{*<@}ezNi^jl5WZF{E?FumpKizh#jm<%sYYgMc?DOPS-L zJ5)_1;XT<$Jc{1D%ignD{{9m5^sDf}3UKdFn&Szj3m|W37a3;U=2DE5MVHNUz)fS{r(LPq` z0gc;RHW&1d)hOfJ_V(~OD38kmt@j3%HgfDjj-7ea6SO&8Oc(%HD8hhH(C_R;FNdkN zK1?ySlxAf@)-!gmMDgAs-`0qQ%M^=m?DU6$%w%a?^zjSY0+ILCZ=mr2M>h+7qTIea zIj?7lhrCf9yMupCJI}CTzDF!*`3I4F10lkL7|USIQ&E)|v!2I-i_VVumex;^ZJZj! zQ|<;PXh&)=`~)>ZWLG9y!{`Yb^|(97wD)&3juhwL-5vzc;$}j!xSAYSeO#?9&_nUq`zsK8UM>SRRhhk>UUFp9F^l#^GGV8~HNoZ43f|A@epdetfTfOdw!GvD z)URyJCNWVs(<&b?Z5H@TVX{{8MTJ$fY0pLv|HQi+3Vb_tV8@}$X6)F-Ls^rz`rkky_ znBn`{G(BBvlUQ=EnfS+jX)F&q>vcFmX61>{eJ&%0RDzoUUPOnByZZqfo=cDZ5P9V7 z^zed5akTS#rRFHias=<#8IU21@!u2ILdOzr@lH@ylZMgX(m7BvojeY5vYk>bdv5T> zZ)2_Xr8eG^t5MxhIV|m@S6;dG-}e(&J)n5kSQy{T!a-N{v(%~N2LlVw7Pzi@*dJF) z5nr2}D6$kG1Q7OjiNYPW^Z~VdX8wUoRc5AuGcL+zJ+ke-<1pLTrwWQu>ox{f zie{`F68jZ=nxcld*+yA04ePixFDYED&!qQXRo_-t)-Tx@d34vn4Ei*zF*!QKI0+^3 zHZ!BkMm(%jOk`)1H^*~ZIO6~Cv=YXUqt+sU-QNw%W^OhDA);=EsHjr26O6V(6#p9e zUY5rP?F1cCSK+vO3MK3>DM~0eIB!`BQi$bQON8_u0@7fg*`zc4G)3~k8%L}vJc>_F zsUobOr4#KqSbvr^L!VeaU#dGCz~qj%|LUJr!4To$4+Ob(|rrd z-_Nt7`RJ0qLq(#J2GRY%)O%^#O{RtzEARJp`n(@ha)aI1v$;t{RnE-|NsVO1eSXm= zpj$qr8HB2QG((xUd{zsevE@wizh$L85$T)d_w`!6Nvz|Q{5NbkWq59r9_dF9nzc8? za&5z26ipi5t{Rb6*_G-XXUbFRO;6vmCscX~6ipDVj`dxbE|{C@_EPRFAOozH61@30 zx7J&`6bj2_H^^v8g8vyucrl9Z@t@s08KcBAqXOLxZt{nVM=}i5eaghGMs=MhaU#Nv zeW~lT+-;x_pC-a-nptw*gC+Ia=NNqd(E|UTJwG^uCJ;JFn9dJG5mfk zbhJPgi>(1%l}aw{H*}XcioAwcu?7!*Aal!68p>d3mfEU%x}a!th$DHOAAd`vF`sL( zo=mHEbb;_jUAAe@fxh#%=JIipJk81sP? zhr`WC8S43Hhz9Q!3>x>%H$gzaRO=^-M`tSb*Q4%}Jo9z3TqMf{gSqYTd;1JC)+ybC z{?ZgbeTq7T>r7@Wz7>Bay3UkqxOo^ZO<(mu`6Ak;X{8ajOSBm>_%Y`~R_>ja{|amb zJpjB6l_G=-Dr9$1{z{Ku{YhDI_mh}vm3Su&JHF%mR*&zG}=Qu>PYcAZTo=N8>?7sRBGjuMLzo8ep1~)(F z4U~K(UpM;ETKxQYF@+Dve}0hbL8ykV0l{2gg$bF*rsB#H~XE6 z%}fFN>cQDl@z#@=!kZuML{)6m>g=)#$A#3Tt1jNxb`3u+y>{78|zmsLc|g(Ckx)Mk}$? zkWT8ho}K~d{;`sdmstO5WG%4$1S(rGkBy55IQBxi0plHnGWHSXK*dg#zwbgY&->04 z)@(0S!9GRgdBaH=?@V~*yoN&?<0JNdYTs)}>!l0S?axv@Fd$sF`}e|Q?YE^prqobo z9qU@T0n$Z8_-~Su6P>@Xme*hD8`3J=+bUONbJ1QokDj*acm9!(h`)l491n4B-XkV8 zELpOctX2cuzj$Cr*xqPEBv!8sENX*h@~6&0xyeB#Y|*qF#h2)%-L-5Z@$oUFcTRD5 z#rPvjkw|v|`WKwkPhN*^>qm3R+F>t}^}+95skQ*4n>8)9z9PUE5z&np9(Na~#9Ht2 zT+5)^(1t%-_2UjV4hgWKKhA8hxTc>R>CscV*>>Kr{NtK0@`^t4(jlGkxZW;w0Cl?t zCXjECYt&g8f8)QQER$oR{eX1RaQYG~=VM1x;`>vuKn8ee#AAE@&sSx49wwoDyI9|N zdS16ThEYPqO!+H8U+@g+za(@Ui9#T1sy(-9b*0Dut9oj-sXjdbQ9Nc=^a>e*x(^cH zQLBGZ;(5k-Fh`xntP7@YhV70QwtzY5gUTMHGS)`W#S8rC4i&QB!F`Q65Nam}hCSiWu<;8HUPB$+b7-}B)cO!NmBLQ} zS+lQ+F5*`IVPtK|g;VddY7_5U`eJ&dNcx@}*34Z^?82*-*k7nBACuR@JG2KBWCq4W zsUXimqb9c)iZ124mE~KO7az8{Mlo_GE^HHDVo!YNdBvOBrGJk(Ao%WR;>!z#pkv z$GwShPENb))Jvx1U6%}g_Gc9JEXdiGWykQsoqkd!I^?^g$4=yZmbI6o>IS_XIOiK% zQUuA4ze55TaWkcSP_~w$puL{W(-DkY^z6C6MBcyLO?i7@+JQ2(2tIP)gI^$*FN#>F z3aY z69Vjaa>>+=Zbr+%ipyU=wMWlduuHFl8Qa;tk~-PV7&U?hU@1)BrF|AR04mH%@{e5HTn{+)y6 zfc%%19MJzG4MLX#_FwcrFwPG;`L7JdPD0%g0DwdLCxHOcGOz&v&?IwZpc7C=n#a)A znnB;l*1(v-&D!oC6oAi-=Zmy9cG4$yv$nEvLk(BsfB2Je4q(B*Y z;_tQ&#>5;9Obkq<0Rb;VC==Hz6@!^r6B>dN5C%3$kY%E-*k z&CSTf!pOox|0O~1=x*br??!LqNcL|f|3}XcV@E>=b2}$=`lKx}p zKaYR=>11y5UzThf|D#%86=eLUgprwniSd7f8M~SPUts@~{2TVKdi~oR-#^ND)D?{# zZLOUDaZ7-ch3{V${$I@h^6%dO;Qt2r@67)RkaI9M{<6d>q>IwQK;&h&a(a5YH_jaC$vw#Y*A;C~kyD}>e1d;KM1kdcK; zQJ{Yd`QEXly5GKder{g!K6bdX-WGMbPNk>sW$pd3KFqpF+*U;UE}PmuP{T zQ*i1G$zZgq6^MT_Rxr6hJ6e_K8Jt}pf4;gmzMnj!V@rd8V*Coordn8W7jIeg{?xgp zVnRn!t<=CcIXkNuZ9Yi6==n3M7Gb~jUZ%1?JzMBUTL1Bp_{cz2egjhm3`1ABdLH>b zk@nc-Dk(-g=-`{Yna3F~YV{+DQEgv{Sia?E%yTV%a7W!twW!pgMlI0)kzU(ljFnD~ z9VuPC3yhz!TWZ+|MsIw5rM2KHb9`|!?Du@*PY9j(kmj8n<=hyxRxJ}p;+!s*ZSrE> z-n`T&8HNLp)OCWbKd4thiQP8)t8zP6$3Qw}YW%Pg#nu9kIsQOB;;UN&f!i75Y+zkK zROLZv1MPHzsTp@3 zt9-eEkgIp)eA)gq@2ruFDdO%G{08t~cT-2y@;nFA=YU?)wSSbF#_8aWwc>4PZcax4 zhx$(QLBl}_4$+xif-XofvUrvS^OK6<2RiYa|{TodPRz=nzAyFu2QgkYB1)J~NXRbe{zO9s%>x*UNhWqFjV6 zQ)2CuLHG4Rk^4&i8?GSRI^2dY)YJVOk}n3Ho4*PopO%D9oLx{e-(!F_?44oAdd1tk zq+cCu1}G)3H);PYp?%(p7NkJD9v6z#$5~tAqZdrnlOjOY?M1`OfrZZ+P>HS{7zv8#lfmoxzB!Y zgUjGIh*hC9g-X!n9_!IhLad7v_ujb2$@_N=_ENsK^fMhsKNZnmDmk2ww@FD+YL5jj zhV!Z|EP1j_Ne8(+N!+*_Q4Fqvs$}Tc>Xx{Y>%W$AeIM+dT<*Pg352-*EZ)vZrR$ z*eeo^N5tQSmI`B}n`+CSoOBX(ZgZukyhL6bWl@W3LQjc;3juE`kKx@XtL2M?7<6Tt zLUZm>-C^22GeL^qP!SFsTZ?s$JU&t;Cku~6UVJKMP^)9z@)c9WSeAn~oe?IEJxK{n zTqaT?j^Uv6_d=8NWr_3#TTot9x0ZP5%0!ShYi_cZ<{teOXrzVC@17;X5Yf20VFk)_ zxRw}oU&VYE`e!7(bP~HQQktRoVWE+FrM9UF@d%N^)Hfp)#>KoxFWYUO{Wr2*LHI8v z0RUB*mDVn@iQ5ka@n4O4y$DYR4HXqORZ1wC=@i;f- z#%++&X443*U8fwE5pZa|Ge*HK?SaTBZ{4bc32%lr=R%M+nMNgO-+GI~fZFl(U&+Zk!+o+dbSDojy zUpg+caChL3`W*y<;#-w%e3+KY>`YBK9`Ca_-`RKW)@g@lHMMgTcG&# zaD<-@nlH2Br;=?4eorQ2gt_y>qQjTTQ#n|a0-wy9XglxAlh>UssqjBWDFr-Evhn@E z-0VSaEh+@@R!`dIV$oaoSIzM?`bbR*8`KY-b`J{gJ`2Q zA+9WVhCKWlGhROuEwOT6A5MXEE3z876aBL4*ixAzQXwNGUc*-{i?2m|Wwy;w*lYV+ zOVur}_-qEYjLxOE3SGy&^4P4WuSQ7PldRLe3`#Ue6B>0hBNml>hzXuhY(`PNUGNlSe8ebx0{o*26g7qgBu(r!w$h9-PBlW(D8k#F(vg>k&jW?dP*xO)6i zCPEeyuFzE|Xah6!+d)2va;uewaeXHpD|pmt6*pbQ7Y@` z)Fvheg5K}jg^G@&n&8{lVHh+$?|+i$HGxdL4mIOgXA0E;R~^OjR9Wc~4Nwlx@R)7I zQhphI=Kyc@$(&GM74lCf3)`Ybgu0db!?~7cTQL(_6vP^|rL<@7R2$vav#R0#?W5Sh zzLG<++CVh&kU>qOHhqfqdUkC1zt}L4pNEE6**@91!GyUQT5k&oat$`8EAP>EOnh)# zeUGOOZRt*yM7eB76HSdyzh~ZC$q1o4t~0T++a84g^h(2)-5#3aOdAepn2d}Uvd$QK zRCAlAev4uGzk5YWulgDmL&dwd-^Cy7LS^rB{urxO@pJ3abi!%R!tI1E9ycu41LY%y zETaMJX%30R>B1ui@!20stkIxMZEN$jY_IZMdLZFllspsN4l4w~{ZQ?Q{=S&lq=kok zkzs)bt;rBATc@zW+rjcHS{jLA&#&8SPYPVPFVDjt`*&C=%g(y(hA!N=-ZaS2Ln%l$ z>iPT$Y*=y)KWcTZ-A5kF89VkO#3Mzb%M4zD-;|n9tDjD##`fQA(LxtjQk`g^u3ReN zfC1mONJ=yrjKNy}Zew{{jNV4vW?oigE@aYnVT9vsgr=fV4(7qQJWf<0u~oJD*w1$q zM;v>NL3FrImDf*y(d;zYdLB%VRldeqrm%VkOPp)wdj%>f5FdkS&R~B$9}`az|c#K z{$Wsm`+WADQ_J~s_K}hI7)$G{{UQa9Y1s6REZuOV=~$t(1&*+txdt80Okub=Cl?sV z1EubYJ_HM_E!6ky7a)dI7|WHXQw*6u27B`)aYyVa$(T%QPhut8U~wm@dcZLEwxBC!i+{}C*Z{Ge!l^!BQa%bDc-FPyg9H4W+K_#043k$o=nHvP z^DI^yFxkxw6v=l`jLI>3r~=^zV?1&=QjEd|=UO)$Eb9y*C{h_(uHuw75$)(wY?S*k z2!p|;SA?s35Y+y@&L#bL{p^3Ec|n)tSu)aK8Z(z(?uijRmex66T`zC)i`HJ}PCTbC z`Hs46hnVjb2+C37w;kvJt#|T>M~QrP#bS(ZK4r_-=*ap*go=#0%?=jph)u9shL;2cy7U%^#wOvR26_RI8@PcdioaO$z3O8a`)msnN$`VQ^gj?Vb_f4ZKR3>tq@^hbS;2-#7BL16-Y?&)t>3o633{xq|HZPnW{TIb{Km=9EL7fO zL1)~Xb;_Oa4v$^UIh;Ql`u7MKA}p>c68zmqz0E5(=Ax=tk-O1Q?WgtHMtK`K9x@6s zM!15tQ-0s$$eP#<;h**di0Lgo0=4lAvkg3+C_ElEr<10vGge=6&~}Z$3#|yrw8;#t z7DNA2)$$%v`9oPn=&7XdaeAo{R9zUujzWKmn248AcnW^zGGGG2WD&)Fo7J(Z5==8sdFYS#i5QpK-=)*g(WpL>W0$t?i-53i5JLJ?Fd=r%`or; zVqLw0g>g}s0y+{k?^#TY{GrCIl)?N~B4Aet6uNMtdFuTYn>8S?wqIo5FzHnHooQ7Q zc$3R-%J9?zi)1^AYusva=T?D5{5tyC0J@7GfZRNsZ?dYW;~?Z4r&v7p3!%nH7VP4R zn3j-!t}Sw-XTxSpY)|)zuHsbI=mO%1uZ4$05WPW4)g{>Pu)YH_S<2Ybkv+~h+R+WG zZS<8I8hu9$6btjC^kobD;@;qn9#rosMyoFG2x=RSPFp)Yl**K5;FjZ-lWx0OP@m{c z^Uo%HD=+r4ko1WK5GCWSRUqQL(=c96IhX6{3Tv))YfIrszUVD`V!mZlX}EMSd*tpv zH{ymt^#bzQy@I)@j2YC#1YW~Yd`r>@}-?y!>OIhqC{c-?-~)+^CNEbgTK z_TGmRDhMq8en=pnM=k|hPDm@>e7WqvJo1YpVnve535mme1?1suKz^eC>Zc7XWI%Lt zQ*v|H>k|$OudUu74~RS~ksEP?`*+gm*1MFyoL!EO4I*tVh+yXN`u4u1m=xIledO>~ zg0~~8f$P!$w3Zp&zmS;qq)*DA6}AbBzeL30Rj~-}VKA`7`3n%@sUmJ7wbiL6_E9N- zK}w~a-TYKs`!a{Re1ewvs{yd=h@8^uRUJ2rz&f_;WP1AZWt@g^DF^_i;clW0_Dcn| zj_H73RuFrlze*y8hZrgD2vB=21zz2`4wWxtpx@%6cJ6vKKh~YsNTXi>I$>G{!Qkh_ zgF}nggeim1^TVV{w5aK%R5B;y0H_y&bb#X1&}DN&!#A)wl2vj2pVz(9v4%6BDG?!0 zi5k9+?e<+BFAX?q4Ez)^tZf`rBuMLkz)n2X#Oq!KpsL#6R&$>g{MJI_zJljKEzC-F z7M2V5bnk{}e${PFn@@e0ha!fY zdNL5UN{@xz`xFX5z9+8vpx~ywQ>F*i6nd_(AY077p8@2^!4A@?8NT}qd8@}Iu42{D zHi~}Cq*yc={XfRdXx2Lg@FP1;yoo$kAQ`!KWpKKF{n0(daCqKq{I+^<+fQ(|sCsKx z;P@R)R-BmrmT6)jZ8g>(j2~fo7SZVigG5>uj7hP~dy1Neq=WbJ=@?em3=e1TMTg*8 zTB2AYha4&13+TUcZ9U zQOD0ScZ7k?n0Z7pfTq!O$z%G7J-Op%>t5_IVP6+i9Qm z4Ai4Qlew6U_z49=)V@3}MA~RvDqrj^&B^?Cx}sE3sSkKSd2CM`(=_716*p|Tay!?F z=KP+dWTJG=WC?h0#?~P80fD>ylOVSj6ItpQILhd#qD{)k7C9WF8uOs}atPtds{2tdYliDd!080x-f}@b{o9Kj6)0aoL9v_ns zdio!=Ntw(P#DmToB%&kXoJ=YaE(>Hw0ZxLw@^*NPz8A3M?^ z&lRTolxU^DTq!ra6DXeLu7EBGi5+1GP9+OP>!a_q&gA{m@490x4RS}T-#O-is=w%_rKpHHz&7HYe?&2e070shSrnW|I@MwYr;lSS_KwHRW=TY3;N1*+sFOmJI@5LRH`TTte57I@0Z*-y$^5!R5 zV~MYstOe9;iq_mBI{wxX$74a=(Zzk)c}SNlb$<*W(JPrHL~vhxW9C0Q%X5cGCV$dZ zA)gG`GNM!Ko^DeTM<++UouDXsej}%cPJSNc;Y>Ms%#Ym^1P;z1#^HW%4Hn%UMb<<> zR^|-P-|g)IN=JK@7JwLHOPRqML$^KkQeVZ0fKa_={HRSt{ zn#>O~yFyzakjFgpg{aq$OXyKO-d)h^4F@BEaz%}Z*4YAp_t;Qew|2Zt=j2kdW4hk= z1eG&hXKL8cT$+~+Ico6m6I1i)4Tu2`1%P6*5qKxx`3wG4Kf)j|{sU>eZC>2JkVT76 z?El1Ly8=ZRs{L=MgHiE2;RAqdLOB~f1t>Z$j?P>jDb2VgmxBz_N4Z3z^i3Lz#t6n< zdWgh|d%*CJKSL{xsKK>7$DAj&qUX?&o*{MnXA>oeJ1Ru3aae>PVyJh2$lE;|T=SfIaN zok)ZfNYz*o&Ha#UBkC!i0kignwkOLDQ1;tV$?zRC&&k>yk64mn2t&Ry0a-BjS(k?k zcO_w~{(hR8{&mB11@_WtD<(X$&*j=LZc=%wcZO86%<&F|0AX#Rq*P+#Hm_yPpS4kI zgMJ(3HE%HM-+;XZ{BFW&*ljJUTV=l`jFW;p$fIEtAbe3lsKPBl$U!K)BQ?!h*gl`5 zI>LWYQ7-h31mph+MDqjVauLaa)`r8pNzIS>Ac{m>9WDP*=7#|$o+QlwU|H~sAG2KD_67g%79Z0lRKX<$^)qFG!F$RX~e%TfpPU38N51v&|{UA+wNoT|5hs{vdhn+jD4iRjqaM(Hz-@1+x0v75YqbNN^yzN;I8RVVm ziRc${c}?m?y;wYTlhzx$>p$(4W$|2q9%(JeOl5kY)^NCnU;3*~XwjgF5G8AqlDJPU z{sh}uMkSzP)Sx2J--94!Li9%CcA{=wlf)b*u6oACCh=ius<;6Q3uW4sOXQQvEy2Er zyk(eUi+Z`Z=vb{c#i}|kk%M-#CorTJ=l3H^|AWp11x?s}Rryr#I?T{<*D%h@i|06` z#=BJA?r>fhD}Ux-L-40VUKOO=ZxNl~NZXTL;{0zSqy+k4b$=lXd_{R__1}_PIrpG#Y&j<=#BVf|t9!+wg9K~P z5^oBnX3Gjstg=H1mS8||R#p+oL&0BOs#38-q!MDOTE@dfz2BDfC8zc`4P@*M1|t=EX%y8c5w*sA2RLT zjwE|DoO>bOY=}g-qv$m%VgkeTlg5FgJ(3AR3jSM4s}XOw#xu_ID9_S#EDws?l!i>O z!qc;hDUhrnEPQ*8@kt%NOVWf6+Pg^Oh6bVpr@!MVIr$9n?>#&Q24Fl0$PD|JFbrlh zj5ii}^l^L-M);pEmKdJ*;u5ZfnKvYaGfs~{cT(UBZ@YUZ?#b8rJ(=Ehhxlupv8em_ z3t{at9wm}(IlYw6W>L)|6GwPre&xf6?9zywy5>H~dw@{XroB`_q?E-ap>9V{w}}Oz zVjzv~Dqxn1(d4&_#^g;zHC^OOH8LhGHr7e+oy_%i9qMr1;_Lb0Y)R!z6ha{fm1Y2- zaH>$bT}LP|F=YrOTYrkIOLoP<^5YnD%;iIiQGcygkn1-Af z!0qQh{wCRZNBf;Ru2n84WRQu=7w^o*p5BlYW%d+%yTsNqa!!1pnjqNIqm7HzhxzC2 z$S-aCOZQ7{m)VyY-=xq0*8{BCmCeCj>)RAe6I*fPJ2*mfs}M>=r>aA#;+eprM(V`` zhIDG%Kx8mkiSD05Ad=4O&iR9TzHxwrrW9ydimL_Kcl+McvSEtV81b8wjwY-a4p>nl z)qKYnizE~tG41aRO4Xg+5ro#nwobJsZ}x4++&w#L;zHp!1vv3MOqLcDltUy}S(bkO zqcgZ(HZUS57PA54&@ef^k)mM8?Yc~1%HHu}c*!q%#kQ?~G?=o0y7Eqlq4k#LRgt^R zJdqXvrpl&k7<-+iqQmw<_08=H!-9MPzt;I@FUGFGl$7+*0-~3Veb>$puyNU!d@H57 zP+Qiqv*Ru;`Mw?tuMB+{y7EgO%X980s{TLMZY;fQOnFe0o?Saamwg@rNui7AAPIg; zMOG9GesqTT+mxB>IqdCg89Y{Pj&VV^b#{2a+`vPF;M2;!3tV{igh+_H@tq{U=n#$L z7$>qwc^sh})^_k4`~^58;6Y4|JlLfAF0Vy0L_L|Hk+~t(%sb3?p}{6I{s>P=y6`9` z2QBgjW@PfoKWP{9-^2%^Fi_I91qp&V%i{OT|MmG`J`xZwt~ry}G)7EOI4W&;H|x2{ zt5A-jYI@t}7T>uG3h=Da{d%{ooOx&xA&Ctk2lach-fXw}(@pohoVuB4djOI%vB;m9 zxxWS52)dT*w1ekonJj8pds(+OvzAVCc0MWA8aR#!bjoP#dsfzWQcx#CP;9eVFrMrA zrmg%nfKh@_0Wb(HT#G3ha^W_Uv%9R%t99P|_hg1J9Sr!57QkUhs6z9@pB0t>K`2&- zx#H%@Wa+YS80N&1Qy`0mlW`d$O!JUBBa4g(^VJXK5-F^4jkc1sX6GT1o5q$@6dmFI z>{_J}{%WS;&qaf|#hD7rji}?kfLl>BjDACXZ^C*L{t@TfU57kT~-0SEJklk80vyjELzIz zk>d-DALl?{{3Xr=|9f0vC{_hkY3bc|=mCj9d8FRcN4oC9D?QUu6i80Six6-31P%^w zE|5dpSPcb|1d^z?zyio;!#4tc$MH6qTNL3FxX;EuPnB7NTgIYD8~iP&0eav~_}C5* zS+;m8GZ#%QJkuZ}LB(7zpPc`Gm<3iLim?M;gr*Vl%#o6xSuhb%%8Hc?7GJ>Ik79)9 zY}Y#AOeqf7dD1~d)49byTe~`wZ5gSR$G>e_R@s3rgn(Vr*1=;8^Ao+J$X76>6$$@A z`wT4keSktMw60_k8_0(%GwbMkZ?p!Mw}$PIU8rfaf>Ar;@$icXW_RvJuZv7CP3e8N z#aWcZM6c57fGjm)lSnmE?3=e@=W|?zh{;r-_RxFFYT6cQEf;%7(;(z5D$BTn2(y~@ zBoqhJ<1#1_Sba*vjA(MbITiO5NRmg-d@+7K^-+fJQp9wGjVbF1a~dDKnQ`W51vpbW zAHGa#8cwl#M-z2>ny&HLS-AYnpoyaWQ-@L4#FawYtJ5tCT%d`s$HlGXXv2Y-R6Ib+ z>IqEJnteQCW=886XZUZAY3*{lJb33|b6~^>+hRalu%6S5h^#Z^*HENUqs=*X1Wh3d z_?z~N-S>xqDpHH-{;UgU@6X)#AE$Xj@ov^KF1eQT+$V&mUn3ZU2GC>F(YMhi6OwMr z%hT8r2QKkY3lmqciQdn|8I3MxM9v`sz2=YQFu>tJKeE;?KlH+i`TM$|Q+{~9d!xEN z9~97p8_G(_>o0nM%pIr(^yH8)rs74mQGFZCyW@TJPypzkoksSRz^c$m;YW#X0d0IF zi^a(~L*K&W%`3PDp)#00YdH|DCz$|! zJ^w}FxPhpT1t}|Akfh!8td%C<0geWqfrxI5r@bc21{))OO5?grN%HlF=Y>*EpCzqK z1(~XZX4kZ#6n9C$w7`t8$#Ly9sT@dBu1o`7wrgLKU{lGUmr(-p1gCo(XBE^p1`#U^ z9BszNY(0K-Ky=^|CdALUpouXW1j}c6GZlF!WT%=W8Gg1Q-Yif$rC>!Ps3nxKkBx&Y zO>y(L9*C%h>4&xuPpO$xmOULbZAq0x%19M|7tyU% zTU`9mAPSKtKi=k0$=2h`^A$oI_TC|uj1~&riCPGny5gA10R&DeWvg1NL&KZf=v{G; zuZa)Elr`j@q2ahSrn;K2#&S!3z}Qj2ADT#VYdMfbe>{SPC~%GM+tA)X)%na)i(lW- zVt%vh)zFXdV0~V?$@g3>UaeZ-aH+xGSduU*2e7V>&+~i1G$k&S92G3^L<-n{)r2Me z6w^OePXhA|PXXIIQVd6_?YF<$VqFa8(j{tC9LcLN+jb)a@iAFsR#^Vw&--=f=L)(u zD1rp1NZGaw$<9%CxS9-&EwmmN86rJpRxzg^F4w~j)+hU&pIPDP$b(w!e(NIyK5m>YS7G1AN?LpIS0O zd#r|jJkuR~Ty({tC@+4|lA{ft4+5A-3bp*JscBi1Nq+(|Z2?`P-t?!az zgfXT@8FuyQM!(--OQwe=*>E*-@H}=MsZ9!60$fLZR4A;1vV?`va`{xi{0;rI5MUgN zklX+25s!1hUnG;7$f%`MRRL}jPnS5;9;Gpw|MBDNJzM_11(Gf~b?4jgOh(w;`aa!D zt-tx2bhoYvVTaIqsoJ8`xTOlFkET&ee1j9rpWjAH^@eKkgnJHuE%%Jw`I?Gf4RTQg z?lUS<1Oc9E0p>8JqBh0aD)N%6&iZ9zJ-fwL1%}LCQp4t`<`{cd+%@ln9r(3%Lmq24 z$z`;r!(0gkW^R9Q%4KLXyLW_0}m=dy=f^;%xz>fUKR?g}#`oSP7x+_&bX~ zoz#uqP<7+9&PN@-9;3`Kx$XCr-W7{>DFf7%GRSl$!nJj%IgWXr)55gJoGB&60Lxe< z9BCf2`dRWHFRM4q`M(_&h+%@=wF|<2(H*i%qoh5DgrP@6Ej*laV?+kct0ZUVL~$A5 zdNGjSPk&EeVBho>k;y%|i^hj=z?r%{^1@%_ z&J)Z~rBffT{Jj-U>{O0<( zjeACDTd-|&k&87$uYE=i>pxFMrco%ENhaJQ9nO%N;eqR}zka^YtsyC9zn--Ms!Oa` zuwd_VL#S|Qy!v2*OIYP(%AAUzV^BDvQ{km)aS=+a*KSWX8oAlsHH0#q47A$PS~EIf z63H+VIyf-)TM@R6Nn(OWY69U)9Hn)gV%**7?j#eEVO1HVTDOMl@-HM7MiLh+(r4FD zwaNpDxb0_Sk`@SlT__NBm_?mvef$KW)lgp08%$`Bi@VOZn9TV7v+yS9e%B{$$@&My2_$Lt5KOSaR5u)$KtBP*Y~x`qSXvFMj*E=a4~1>YZ+1X@*-IN}H~U zR?>Z}uWe45I;YttNU+Bn4|hJ2Kh_xDf2kYTb{>^{CTWyr{I_K%ck<(C>c=X z@I=$^iGxGlr+iqkfdoJ1anmN8)ew$PlnDqr>Ms(`I*t_J#xMG$^qUBL*0$rIlw|sB z@4~ZP%P)03D_)Mou_9qBXckJ)DxjT?ofHVXl@&Yh=_#R!?SDDGj1|dRE9pMpl+W{S z2x#(OH77hZ4GqqgDbG%Z=D-}85@3(JIM?W$xS`hcAeGY&rc;bel$fV3(1IFzM(6aF z!gW81M!#%k(<@(kUz*1OFwD5dEv#DSqX_)>n_O)b{s?wxwavY`IR)$d164_Jv-Tih+2mZq5iH(yD%s<|G&P3h2+w_I;p%9730-u_>DMM9 zl=pd*{JE5G)Ah`D|Cz*)@Pbki5j|!S7!D|mii&v|-qkK^=cQFgDZvJEWQmiK+}nP- zG7mc6UdD<{j#@m@}?%E zG9{3V5gv2NLC!`^w8rwcIG{XTq-n-vhq-5VP%IY!G;0*s3}+rfGvWO1pB_7meJZec zQ~_E^!%*ygwH@&?cR8hCn(dwNB>z-_lceIDTE7yYOm!1kPEp33!{ON=s%2 zwQA9JHRyOh(>CXN1%^2f-Zd7gD8^GXl`#G?4_$54WNbTVUkq^0I{g{LxmZT#?2AZx zcU<5+7D)s4)y1_bB)4iYh*sWY($ANS%mE7y_GW=N!5-bNp-l6bsL~`#ZM`)pa$wjA)N)UtU2n>cTo9A^V6#Vk=d2G4!YCl#|s};?651py)E|-EZ|%--oG5D{a0VJX_2bB-uliQ@J?j zFh&YSsUjM?&!K#-E|D*ge|m6M^sj?uTxm?maT{lyyq#$^`gn_B{*0DL;2~uTKWtmG zEENuB3PH^K5TiUL4op=0XQqP-Ip)II6RgZGT9Xzh8EE00ja}1rdO>(!^@|7SeGPY5 z+SJ6=6IQ=8EdB#X(K*7MZ_`Fz=<|F^cu$JS=}1qKjR2qV{73yV)(&TmU{P;aiGRI! zfE{ybZ8M6TfAX6W?TJpl71;RdQKOMQFVPwgkP>A`95&e|Qqg)f9l&seljTtx~&RsH_s@sG-{&ez0~ ztoF&lAJeHPeo(c0kOED@Afo$s;VbpKCv~>gs@?DB`KY3rq#k8pQ->3&6%3twRQJtL zwUkT9TbxwZjO)Zw@<>XIOW~0FhN~FG?fLOlhf1dYSsD0{SuymlKE$|geAA})j&uee z7p_<(NM2jg>hcxz<=2KFoR6M+wGAh4(T3Z}Jgp+V@p4(khyrevZAW?H+w~SI=F-+B zN$4;2EnI2Z{fs`xmloT7-{*y)WRUl(vbJ7M)Cel8x<4cngE59&wGdtbQ{qaxF@x4) z5fp1EyYpscVqT`%(R!86tHD&?MH59Q0Og<0*~w+b;~gNXbZVHoOWamE(wV2to!;06EHP@4-C@+_;ppg zBj~m8OIXe%dq7$FLN5#x+x^Da79XL8IFDnwl+QeTq~p;9k0%aD4|G3n_QEi}lVg8M z=7OY-`b-NmJIUPt6@4jsV*UBT0Myof>62)B+ble`h=vK6?LU4zzS2@jBr(ITbKmT_;L`Y;4A$ja73GN^G8GmWr!Ur?33`++FmwqvzuW)FxE1mdYoUX{*Ug8BtVAU=J5 zH0pSy;KjAq^6c_tQC>ilETU%00e=O0xx0E41tm>lXU?J9id1)89h`{h;I1r;6V)e? z*x1Llo9fr*i(0!Y))lSlyPNezsw4hm$}K4-2$l*~+s`RO?XB$324Lq62Hb$fH7pRP z4JErs4z6^ZK{uS|KFryej>M3DW~c3LHo2TT*sgs)4;BtN9sN#R6N#6usOwV~Z(%6% zjf+(9x(df2N@`L-n*Yf)nKG`e=eA1&-rGbs==@}BnjP;Wlrr;TnzVgBPksfRF8QZi zjlpTRqbcF!Zp%x5CEP-XyOPmu8!@`-Nlyn53*XXMQ(Go9?8o=*m^8l9g;;p&Qf{m) zt}C*NcnZ<^_s2^GqSq(e1Cu!xn0Wg_x^ZLOuN~|W* z@^eK^<>qr&40# zF|jt8)Xf!W;7?gjv$-dyx;%>fO|o)ICFlg^d$-0F2lKk$Kr)8w^W_=qvRd z@>F4o!iCm%;)VAPde^hZaXfd^Ep3<8+9!46s^eK&xK>W1!jLewK6CaKBH}vJu_P=BF)+Kob2V4s;g%o(!Y4;Fp0q*$?EkxDU5~Mkz%7_=|dmL z(b)~fO794^Rw~&akKLuFTS7|$bbo$)k9VBn|4G2XNx>U)Lx9#oc1!{#zL0&n%2%Q} z!WF+Y&iiZ}&lIyAb=xVKXS_a8R}~N>Y{;it>k?u6GE=GKJ83$Zyc4nvLI4iI${81WP?}2fiDf#+?8C>z8C9UV7}P$N5+YSw<`cixn~|MUvQLAxXH!?)aW(Y>nG1 z9T`N^P8(1(o5Sji7^*K*I)hKl$Uo7o;jiCI8mR%EyumA%!9;{=YC4Sy{2xyyp{7NY z*Z`i}iB^k#3VyPUzlJ~3PI0{YeBNKqZ?c{ZcP27+Tsv^5~Rp zrR>GJe^Ln)<-T?@Ya^UZvgUYrJp?izrWMJ4ALNQhHyJM<UR&lx*+0T@3Lg9ef}-a zau;*Gl*XELLW)*rlHq^&)}1$}rsl)N>1Qm1$62(naS?IryO@yV>&6$Bse(2sk=tCD z=U!;3BkP@k`&tgYd3a|x%@E`#I|xD9Bg+M@4a$+3xAG&7#dYEm^5)R*^7LSMoW zc)zm&AuuGz`T8uUQ1lNs_6L;{SUH&LtzNF9!hO*_<;5RX)?&+@0qhFKPN`D&gLA{r zmsTCs{D6Za56FA+Bl;ePlb(-yW0!ex`p-)HVxd}ST@_F0^>)GurMWF7Yx?60ZRwd! zW1)z^BEG>m5FoHfYPp+c^xJ_Q#>*zJe04{KXBIe}9Oj8oqE7TeIwnfHt7el)?FQ3j zLKIDrjGr5yf8Z<%-|4La&Q@QVZ3MAJ@oSGot>#E$u+KF5Rpv#09Jt}HwA~V&8!`et z^qlNaO%lgpNHlmVQBsmrsxIoV zb|t(NOoHol&c{#uPQO@q{A&WV9rpS&nM3W3wN4X`*Bu$Tm58qusXtS3=BSmmOG`c+_mYwMwVPGYQ0A~1~Gezm*ks|8`T-1h0s96<4{UW=Y;kR*VnGy6ouhVk4>dc$cHD8AO7rsrza7uYiv_qZDl=FN=Rhd6^`}wdRP0*`b zCkgsrlYo6D&i|s@Y_&u1W!IH;K>SYSk-L?%W zA8SC&z$5-Ta^8$@WB(CH*NvoH;Ql&b-hP;XPLv7n8pmhDajO1_r-=h`f?sU!xt=j$ zAy!;A@ey8r6yk&L^UY=7wnFy3s?1k>dnTzkF9#}Cf;*WLrJO-;)7v>t8gyjYGK}-n8Ja) z5nWFPs-5SR@e6C4E{fe_(^#TgdCvFimP9JylOf|~Ikh=df@ePko+NZqf%lXE0Eh8E z{{@g~|Npdij?I;QU$lYN+qTuQ)v;}#*zDNp6Wdk?_x%2K-`;OgxBoN*7;mhpuA?H?$phD6lGh*3|2yws-i-bTw5RckC1SH zyRAXb?&IQe4);c&`POlgQJcr*y$#8`Zfjd{Wwi;?jUV0Xdb;r@4_7)sW9*U4NL#%6 zY{U0Gr#ExxSbS+REl_!r`GIg0*-ed2=X>0zT*i0|S;2OcVZ-UkuL``nz}DZKjx_yM zj{i*3`F~MgxA673uj{^`MF49q%sN;l->Kc=) zu$X4N)nz)89^hKD+@XmhUL=wtS_rDuJJZN(x$+MONdv9)fzLu3z`JT!BV2iGqC9Op zsRkDPK|BYo>QAqK437)@DNUtvBc9PR=|wze z<3azr;(lyN&0KvZ`7D{VWv{QT4Dd{yfo55aCgB==HuTlaCPO_In>lp{zyc*@rcV27 zGrQ8kt9ja4!{T@@z8VU}!GOeu776Is-$g29Wn-;g`ugOLm(??BmboMFnHL7={kYEW zkTFRE4n^fTsl#{Krz*sYan)@Ij(}6)$D{c`dX)(tFq=$m z%j%v_avi}iR}`>X@1?CGh==XJe$`PyNk z^4`EZR;;Q`uWH-oiF+WWw;b4o2!_tTCS<6}RM8boH%s){pwJVz{sHP~YzWM>Z#x_7 zwtC${ASa>B1Wuc&zCL$c&&mbYi?<$*G{DHfs<9^?XieYGbwq}aZF%uP51rp-gx?u6 z(aIeOqECTfLHHcv$mHRqdc0?CkeUlb{HJ<;w(mx?2_L^3k&>gIevHquw`Vn|*%l_D z501U|B?%jP9~UzKK8=l)a&?!@M(=XA^A*kTI>!0D;=*SQ5_496HXyXreR}Ci(Ca=e zM7x)sOCqKK`-&|a+cyI=o2R}y_Pm2W-PrIhMg0TdofFJ^Qvis-p`>U!T=CDp4a z%dzQsp$}KBdXXk8@k^17WUi%?ut7z-i zbeehBt&qMY{E)XSd6v(Wh}L{|o#N4Q>;&P4MiTVeHSO`AzU)*&vSFmoj^4J}KF?i5 zYShy&22a7PBM`R`R*iUkjt+9Q-Fxtl*ZHgID{g+buc;a2P&GDc(%T`eE#=iU0yn{` zG_qb+>W#g8P1&!-MEo@~KHTXyU@h6uOrq(l#VFlXp`h~ZoX<`J$B1YyLanM|3t;c}WrouhEGXQSNbgDZRn_|Hk}=UvFyc zo>!>>_id9eF5<+fYM!6oJ%G0}dyN{}N(ogjWD_>oh{&BkUce^`qum%;4)~v>beMG8 z@fe83umz6*&DKgsy{DEl37iYnFArpk49Pd@Zux+3864ozM#D^)*f-uk(bN(Iw_>DA zT$gMOeRD7jZP~j*9)g|WXR$Qj^>d$TUiysmk<;?JFO~%>Xs7J`Q|FqHS7Z$wxq%ty zHbVU_3zF?i>`UM3Gt5lA9Eq%`E7hrfkHIYbLdt0xWacy zSbA!HB4W{<8r%^iwW$f2uScxGCoTmi+fkDKt1XB*q>zTw86(OVHk-Z#_2wPwmw&U+ zr%K)srx+~Oom8M`6<7`{3>B+tdY_hEm%`wswIckR_q-LLyT3l;&Q$Y#Mb0F*b8C%& zcg)Z@xNW}xMWGa|*ZBOAUl)^DaBS5+};J-~#?Z=Pv+1fi@>&BH(SYa^7gtzy*u4UZv;SpoUw6C^}b#T6R z1K2ZS5phb`13`lfkmO#mg_F)2pfP zHSf5@I(u=0X@xr#9rUmY%K{pm=f>zuSw7!)TK8cI3L0vFdQ6G73TX=9x`>5VGH2-V zbZBf-0im3l8wyXw`RU0)Lz=^uXaab89hc91I(?0W6xNwZD{c!V868KLylT0aI*+Q_ zwcm5Cla-^h&{TAKY%j}rUOJZWWs}Q#ybu{4MmCM3}{CtSD)Nu3#L;2(R4wRKQly{LuktU&8pQnCVM44$me`v zy9$=*FVx(RZQR>;RB^)ms&d2s2?z>&&NIXf3&_tPJM2?n#dE+8iTfw54ood4J}I{Z z0Z?Gp8hqUWky}iP;KASq+eqCfOgI*Og9MvI1{+ydrq8f4J4v$d8?c8Mg^M)r{QEIJ zx^lhm5YZCIDcym zdLf9>2^I(?yaQP(7sfOCd6?LH1lsw^kmPyq>1AO;tO~fwd36yGsOJ@VbdJvc@ z@|TUi^5EnRzPg`)6b^y1o2@QA=b2KAApz0q7B{$BJJ=jlI2WYT*=RC)PtZ-Q)G!}} zJ2!oOT+dc|_JCTQ+bm}~{Pu%0+^Plny-uK=mAEQw8Ve7%ntQfCXnt=_gW_s9t*l$s zeTn0fGspV#%r*J!uj^M0NJ=xF$ZoMCv^wone{boYNRfoVN`Pts z4XC+6`}8N8KsD85xhIxALXsTC|I~B9CY;1^Eb_*9aS|Ipj8;r31FB$8y%Z@s-jV)) z+T-(7E4=o@)a)5Fji}N1z{XzD>1yAn!DDkikWo81uarVd2WpzbkL+>Q7J!Ar#EM$- zVv2hOu%_m9mbEp+zXQ4-cK<`2&`ig8Hq^PBZ zykOa}3|nk`tcloLw~ao~2K~bsCf8<*i@V=?YU``K4h*a{LkGbNR&9_OXZXHyavx)N zzRN^kFDMu5y*R4aPZeJu+y9nzw>`>vc3(QE?!AK2ZUEBnZPY_@**sR+8IL8`6Rlx~ zLY-$*E{|%qVV-b{{pjas%c(~mVE`SU>7LGx#i4K_AIx)<`?Db;9>hf?iB2m3H~^K& znxFh8{MfVm+`;`JiCM0Ps?vV*?u_l?ATd%s+ZeZC=@g*MY_eW{@?w7AkP zjtjI0*sW3oL6?-f7D+VXb%Y<3d=RhdEBF{yX3l=%ccdQwskc=%e7Q?mbK#0Swdi5ZD};VXDvAhjJ4(Ar$5j=y@XeavmHp(~_upy`IJ z{hh!qR|tv13b%Yr10YVp^9<4WefYpWLMfY%4zgHW1u2_NIJBVkrAFhi2QN>3iZ?Lf zyhck1Qt;Cz=b%ze!QPJ}uGXl9ox=`hh>y(5{8pRstrcNSBgVV8Ew@NM$r>_N4GC@tHt>K3&Uq`sY!aFyjGS+7b7<%*K8xq8ye<6zvCpddaZ z>u=7*IRWpm7#iFM>y-^B8~mKUZ+`11 zojxUq63SJ;6|TYbC;SQ4It855w=N`ezJr3Wpp{y{UTjyt;#nk@<~}su8*Z2mep^it ztY~u(HaWqb;is#J*G^1i#ti5j!*)EU1IX3~gRQJ14G(I}*0moXLyzM~KC5)Qm&>L) z)8ZI87Kwt)I%Ub&?C&Hvh zUF?q&Bz%*fGtHg%`huR#rP-v0M=!rXVA>dm>n!=*BEDuN5 zE}j1I+A1O`Oh?XRMgB304r<1Xw-gjS$>+%3xTO%o)gI;Scte&!*w<=-;n`<+2Gty< z!MQ%QRqIBUcR^R!k}zY^O6rJeP^;0ci7@K)=7f3aQByEOLdbyL9I-YkTa|faIQ_JH_5m=18A>GsXp9^XPo#V0%zeLtbx8YY* z%K_c$h+@DyH8Ee=p+hTy*xtBRMfjnEN+B+fmZCT4@&T7MK)h^*5|xGWAaPIcVh>^C zU(RhbgH3Td>vyWIHc?i$hCCiG#0G~Yb*gHSvdmdms96L{DlNV370hjPTcMX$6%2XC zuWK&Vf=WIP1y5dxa5cy!{<8w5<@pKcGADB1|0p*^u~y{{7sX1o>1fY+^eVPu+3`=%j=shZ z9z(M6fi6fq&jFSnB7}kD$u{}#h1QCS9ff@%f)eOYT^ z2w;+79A)Ly7g(tA*ek%{ZNQwAN58q)M zQTweRO0~M3F8oyRgb5`{j*W{x7nab`Q*?IO3PSST5?$Sw*i+nTY>dW__1SHtf@Uri;(($;2!+aG7nqtK==+w<*COgKj#8*lw z95ij%+P|TD)%t54DDa2ljqpNrDVca+Z~ZJV|H1 zs=$Gzj{&S+5T8xla?O7QEGAN*u35XHn6l&v+G^yeqTIs&V#|)c?2=rNVfwDV1KP4~K`z5d*p5HzI^e7XD=AGm27|MC2fXiLe@S(hh~F)h@% zF4T3awgj4g`xw%z=0otwM&!-5ze$Q|0tyhRG%xO}{=;=L50Xw5vPPicS)Yw5&!Y9R z4go89zX9`r<@icBl~t6JGhW5vJ&6?EtZ{uaDy*?2iW1Xisl1fFs7ziO)AElUqI^Dw zHdaj5Z0|qOa=+IQL=Ditdj=jH%)W!%EDvGjyO^s04YS4qcm@p@6{8S@jkG6gE~_|2)up2YV;u`jLZEs%4_M% zEaYs}Qz$9#?dd1rUQ;JZK2HZ_6}~2_)T>2gGYp7ZmybcqexqG+$l>d}98;xej|2p3 z@OnN;wAr021A*@=Z~(6H#KUpO4mg8%v~ed?Vpem}mE^w8r=@x8%)hD2!jF*rRLwqR zyp(jwKOJChz`vL_4kyBAYbuYyYzLkYc0I7$Qj ztB{LkF;YgD!!El05{7%h{bD=9kL*l^e#S~!D=DwLnBtMpVXyGtFI9J?l;pGX{*$|_ z;0fTd;=){Zo#=i~l&Fpfy}qLu_>AV)|CdU+P)a%Aw_tp#qJGeWn34OCa$VQ`&)e_( zY9+p{Ej?X~jnmXe*G*AV2b4Ec>~S?IwaOxl$bbzYWgR0c6w^AogeFg1CXtPmn=u8acAGXaffA z5StZ^X_BAW2}&0bX69E%)oclzDiAa*#R?;ChWVpJBTB7Gq>%x@#AX^qqZ)DjY>6)n zLzX`XLe$Ci_Jf7es?*UWJ=+P@U0R~1M-U?2(WOauO_E~S$Ua^F9xp!Ac_PZVIk(

f3g)NEt&-b`b8Q_)T)YmTBg{@JPD)sB^VSmG)0P=Vuu!WFLfjpgbV?$9X7? zttO1_4;WQx|K&Nu1tb7A6*l6l3Nsu~b@IeS6u#@d=@@Kki4hzA>1c}Fjuqoq$5xI| zjkWp&6kiet4!0wXQM{DSJKoVoX)zVW=Qx^m6ATm~1iC&xgbXs*?e7)zd`;L&pJk-e z_<<fr zOggQDjWt%&ux`gz%%=>wFI?ZFqPPZ@=JEgdCn@SVm7rkP+E~L^i(2rmsL6gyR{(pK ztqMAZD-{Au5z(a-^YM9pe*s0+c~LrUfpno=a@jXPaJMGy+`@wM>_JmPb6wZo6%k2o z;FYQwXHA0F|-!8+gow+FP*6!4j~vkB}){a<|Qy~ zU@2MVyx@`EJ~4Joe9eUU$$+n%xmwY#7$#xD8+pq4TKoY~t-|D$kU>0s>5s-FGt>%Q zx-_2{;2eJh7W-b@J$>?;Zm@xt6%69z<+AQ4VceME@2L{*dku-azjPNvp7oktZ4VVv zY-+0Tf5&6!9nW4F(l&FI!L=BMtii(@bfhbUe&m2jnb6}RB51%6-f;(}G3|UzepF## z2r&}NL^vgd7p1WrdwRKd zaeWoM3>{;8{$!A*fCFW>?r;7*8aZMGed1MA$LK0^?}YL#9sQ;ER0AOqe6CfT!>>KL z6T@u6l-u*J!P!V4ReQ27)}bp4{!CH7c!pWKIMl&nS3+kCl5WXnAa2n2_XV%Hs$cD~ z!;GF%7)54VHL` zNF2LWqR5tsyfGVQh(IHxDtei%Ee&C@Z{mziDu&RAMowQgjmlJB*<)8 z{-o*r?`(!grbHFSXrN4+(CJ-A@MSB_mJ>$i4Eta?r2C{J;dfK>R+-(Uz4P*XUccO1 zx0XK0fWLHAS3~9ay}zuM;j+1^O7zd7&I228@@yr^j}EWqMDdi;_!W`)?`r=|N# zMErArALh7#@$B`yL_CW;K_;`6H%RlbWaAmxEfx>~7%x#S4)sUtc0Q8s-{|=V&O;k* z^+<#mA>ugfJ@if}0;q=?9eESiQ8r8DxbcXZ6Y2b^tHGHU_tf7ywPr+Jn?2kvOM zTyJp|QP|P7yshOZgYTNmWh77qoo-J(KcCY)iBK8<^hs8^FPo{EHCk2S7fZt&t<(poQDh(>o z%xii1hbFniy-x>|5)+jX6h)&<4$i4;5hGW0IwP`p)D&|C)56aX!q7lF&cA$&LWOHQ z3#ptTGKHSBpr?T~O3d}U{=PeG4fR_Yh3T2l&xj-eGmcpH(ijn2Y@XGSr2f3E9?#J` z`g-qY$^^wYHgqjV{%N>9-}Kyv2b8|sxyDnWGwfIqhBImR+r@1R z_0BqUEZtcpntlsFX&vsQb^ux3CTQjEEa+J~9q#j&EjS;)m5ZKyPI}mEEmiynU0JwU zkRC2~2qhO~BHF?CwV%y)Og{f;s1)6X4s(!seobpov79&$aVqiEy2c}Ot) z45{FRR+_twdK`afP!i}KQK98HgVc8g6^RuwsVA|*WoMk_!S_pKkYoxGxJH6Bl;2Of zEi@BE#yvBGg7E6NjuD%pZM_G}>!4|nA!|`Qa!oS5xX%kTZeJS^N9vM;QeVQf1oS07 zRtoyoMr6|dm!<8vin3GhgJSx3J}OBl_6{lfasdff*o+WNf~@m9>;4y>`OC4|wZWy* z;=y%>ZeX?S1SoPgl)?xmplf4OzPcK=IJSo-n;s5ndI^qGo483>pxEqyxinn=gX%{e z*$eSr*fAOZtLWUMM)3CmI>}yPrA(OpdrkYKQ?Uns(5VjTjd~~~^Xw=1s&yv?=j&|g z1)%U4Ac7Mixaf%Dkt^=4^-l8h*|MY1^82uxTu*$sC*$w zT5?vEpwe)Hl4-Y7`8x$=)P4e3Dp@@u4N#teKbT1s4v4@*J@z|ft{Lp|QkkmSRG$2S zj@+40(@&N3aOPty1e9SOm5T!qOfcs#Jiya4Xf``Vx6RjME!A1*EGfviqoexv~ex5UPakF z3{#Tk@39L%BR9R|5S&m;lCc!V@H6F^GX5MiyzNW(+PgVTQ)>r+P_*TBT&k!WhTpC5 zs(238r<|>L(ccTMko0v>~{yNC!hoVp+4XG!q0E{K`JqG{D11 zda5%$Ub<0j^-5RZTkay#*jicjlEUUk7iiM0;R*yGjt62zSD--DD8x|eTAKNEHBv2F z7xlyb3=$LJV}bb!mQDiehbL_T*fh+kkz`LCxUSmxQc1vNLr|sydaJg3LuMgCM z8Sc2?ux(iMBccHoUZu4AEJK-m8#xJiI%_tS&TZd`bXeCcY z@=Iiny~dvN#!QBGmZ_zMC4AB ze#TZJVfZUHRkLDz;;B#d-H%IGZFXiuz;vV!WGoP&C{v>&Y4MVXG*OnKF^3rV;Z>0s zc=%7C*9t=t;uP+h$kDG(PP_N3mKTK~f;3QyVk7?S@=|zR0;V>YoWfPwZ!vfFI7WRc zXn`dvy*S47(Vcl6bt~KR{TqKph;4faS!v84)tdT<`W8yp6G{QkndW70CzdNj)pq=E z?d$l{YJ$kDD>wyuh^Ur?203VoWX#KdcKF`SPmJe&mt74r;dc1W#>WM_>|zlaxZJ2p z99JzqFLYYc)1gNhEqhCHzweRxtFPOS?K1n$?C~ZVUB`r1xK;0|JRkNNf z0~~*q2rGwJjl_6&gjiYM9-#&ciIZ0t`0@GMsK{q6R5cta9Q`;wWbwz~lZ*@T_hyMP z!IOa4)%zN%c~vzG{CvG{Zj*rc*F>ZjEAW;zv$@d|HcueND!HW8vFgznkmBgJW=}FbI^os z480OExHNO4hb|h+)MjoqVa!ZU27{wPM}rjqKyBR2wE{l5-~O|%j*iIsX;uqQQ;kZq zu_R#(tSb1HYT}jIi5x;tLKnvFO~zK>(X_+akAN?2O zqpmDAP!{vQ_qxrNWsR}sIdK7gm_)F2bjqkf;S({hDyP$X`(`XP7PEscxGnFs7PriR z>IZpcyzlybs-ED8CmLa-Cxj)wU4qCBfLLm4%4*Jm=tI)P-)LeG7ocS2W&!Lte_9ky zFu*<3I^bY!Zb3`GrK(KP7US)Ce9u-(f7568xvJ+yrvnx~8F~VY|87;ns46}-+Fcy2 z{6gcdNPz1^zcUhJ9v5N821_sOocA^b#%~1S4CQ&NVuczZ>sVAjmM}pl*w{>|Fy)(3 zjEK_N@Ny8-%S;g5%pr8O!?&$pNJn50ilUK4m=?J{q1?e&KZjwoVFWCj9H}l6lVwhlv~ybS z1p6mp=vG@4Y(vM(;K#HPHK?9mv@0?u><;kH~MJETwjC{&@D9^;SGv?|5xabuq-iw)re;dSXZfWQ$HyU+lFfutGWs z@U_cqSEnu>w3!Xlgsk9G_)8Yn?3Gl9+e3cMXy{+l#tInyG-H4~sfMDy==2!UrMd%C zUbOTy^K>+^rC@jCTrJL(`M7ri@;W(!T|4i)2)>{70csL7x@gTSn8u`$ zVCk#VU}3i=1Qy9##(wYYvkaf3O9@RI2bgXl`W??(h1?G|*vmLxw^Ys_my=r%&IjYJ zIB&yDa}U#T-wpyoNd*zU4IV+FHPBV7FA(X>0MU{0KnDkhC284D>z5#v9Wf zxy=Q}^*n7fVkAYw(U2)2L>D0aM8A@VG7bI}1glgjAG0Jwp-}WR;2}b6t(HVDBCjg4 z@KPGR$f1q~anTkMi4IM|9gnpypk_@(B`qqYB#VdEe`~(l)q8RC71)fCpzqt$TYCxo zl6sn+Im~_yIG*<8KbD(6Q~BOego5w7sZQSW)3%+{De>x;doZE2pC5S^bdO`wSYs)Kf2p4X$MvhisH7klScA{6+-qCKfHROOR^ur z*wG2Y(~J@svHc*PFB~=&qUE#|`45|S?uIic>#^gl#f#g%Zj4!Z{lF|xR_Cht!}(y1 zNECf*#pj)GMufcjWhheouMIx0|3ISnhjIi{zIa}kt!frPCKSb1igx5EHnGR;M5c1b z633p(tsp^{`&vUMPZXj_YElbGdUmQ?$*%0&A$|M6$|`U48e^|GpCP3O=fp|Cg<$Wz2z*zAx9{^0A?-1wV?4w(vZ;EIdupq?{hmObiN<$W|^Jl#Z82EX(bN5O*vJH zNF`6-v|bNkHn-PJ<#!JP2<1v4kMUNLE@7R0s}mj(w!F`J4C0Xn4!e-nR(sRSTCgoP zQMLM&;W3n()(P*iQUU^Sk?Yqvxq=j1wbEG;K5t>o!6h-k;^hbAe+Du2K(^ofYoGhe zs>mk6(3x>D8g#R|`c4{N>1E(r?!@!)cSN?sW08rpmz%xTcLJhj*CI5?*BR2y9`Q*a`rGv=SvOFnMr#|!Cu=5$!KFfP`7^v8PFkin0UhFA| z3l{m^4tciy))L8oJATs2S?P@ma1M?TbTNDE=2^9973$kqpL(;T|KblCRp+PavZw0S z5YA`9h#C)!XRi3?ms(ALtQoe~xb<9F+>J6V7&pVS8UEZ?fLKFS<4+*o)&6WHt7t~G z_0^>$tsQ0~Px$fe(xfLp*Z9R0F9Fj{+^8TvBz!*PF9S4qXxFDqICNVjP z)?i_eL|=r4(I_Un4}R`!iI^ENFW$gFL1pLus(thftMK;m%G^ykzM9$hx0p<3dA!PY z$o3gE?SR1`KAwlZkSnF_^(?aF$!qa3Q%V_>aF{)mR)M zhAniDtjFb3HOt0!6XNo+wNmsSJtNFnwAJP9*N#w_768 z8(2MYLqL+*-9W_AxUJfW9_(Mdz?{QQ@y;d}X9x(1`0f|ISzjj~AFPWIqp`Zc(V(C# zm&2AsWj)+13m(_K#)(>ncz5x0&gP%*qHm6S(BI=LYVDu9ptnjwp`V*~bhYY+H#c*C z%$@Gpx1ZbW213``h0c;>-zmq+x9Y5fHBvusWUb_$Vi--XOB%A##rMv-?JkW)iWWMd zjV?G0Fx+PIW>;+$F`uYF|IL0w%a}Fr`1i^-$`UYpw5pJQvChZxn-32mtyY$d>-%-~ zxe;Gq@;6rFu7uMrmLrcgSpaHLOemIk^%Sm7g}I);p>7w7kLOlqQA<1CVwPRXpYwY) zBYAYjOP}tpvmIjl0LdO-%dXtE*SpvH^@*1pyIwBnc*1cik!s=y^{>s5kzRrX0gXq; znP}tb2*$khZ&3K8i)}^vR6B;=pL;mUTDg!@@iQAKx>ijX(B?@X(wbQbOaEw1 zG9cE&e;ak^+nRIx3YB9t{A*{S=ys*qF-?_%qwsmS+~jl!8QN%|CPUF=(iVCx&@Afh0pl_zo=o3( zQDYtn!VxE*GYPxu?AW~&m!77fa?&+m`N8d)$W)uiP4zBY$}ANq($aSyTjWlgnvI&N zS+{$gW|e}|NY|T#q_@vlEr^jrbj7=Q-yg{LLV59iUki>4n{D{XUjdG&@VuSz zR&yiiCQ|JtGHa3saB0CO<5`AHa+3I){vZlWabsM`w&dh9*XJQ&-D+n}2*$pxeLJ%p z|I5^irWJO5htvr7g19<_yUcMMa=_0@rpHZT&r0Dp59*7;f;5NDQuatC zF`vlpYC3F7A0aP*uyuajk|qe2w%d?tv`~EY-ySG$bx2Rsh{&h$wDSBSW?8gf4-v1Ot3oeXL!kV{nez(9K)Xrf{T-J=pZ zYSl@O1Sh)l8mn}su|4NL1(!3eF-nN)=!9Zj6N>vpezc`^kGZ9d_uU@DD#XFB=bf`TyB|?oYCCDwcO81|igt&q3A~ z2?lomQw8tShu+LvP88xzH8Lh93`8W^4?X-T4<~z_f(02vqBoM zj_n3DWn8{2nBL?=xQX+M<9eB9{Hd%IFJ^=eKBJ_3N_oj4$bQa-mG<{4TLC5&*F0mh zd>*I=VPo7$mTo0~SRX<9=zBg@>nrf1fp-@(#@|MrK8dfpJ*vLH5$bW|*ON%Rr)rlB|{2!DTp%DN8 literal 0 HcmV?d00001 diff --git a/BookPlayerWidgets/BookPlayerWidgets.swift b/BookPlayerWidgets/BookPlayerWidgets.swift index 9522a7400..06b2e8770 100644 --- a/BookPlayerWidgets/BookPlayerWidgets.swift +++ b/BookPlayerWidgets/BookPlayerWidgets.swift @@ -18,10 +18,12 @@ import WidgetKit struct BookPlayerWidgetUI_Previews: PreviewProvider { static var previews: some View { Group { - LastPlayedWidgetView(entry: SimpleEntry( + LastPlayedWidgetView(entry: .init( date: Date(), - title: "Test Book Title", - relativePath: nil + items: [ + .init(relativePath: "path1", title: "Test Book Title") + ], + currentlyPlaying: nil )) .previewContext(WidgetPreviewContext(family: .systemSmall)) } diff --git a/BookPlayerWidgets/Phone/LastPlayed/LastPlayedProvider.swift b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedProvider.swift new file mode 100644 index 000000000..59877c841 --- /dev/null +++ b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedProvider.swift @@ -0,0 +1,129 @@ +// +// LastPlayedProvider.swift +// BookPlayerWidgetsPhone +// +// Created by Gianni Carlo on 30/9/24. +// Copyright © 2024 Tortuga Power. All rights reserved. +// + +import BookPlayerKit +import Foundation +import WidgetKit + +struct LastPlayedProvider: TimelineProvider { + typealias Entry = RecentlyPlayedEntry + + let decoder = JSONDecoder() + + func placeholder(in context: Context) -> RecentlyPlayedEntry { + RecentlyPlayedEntry( + date: Date(), + items: [], + currentlyPlaying: nil + ) + } + + func getSnapshot( + in context: Context, + completion: @escaping (Entry) -> Void + ) { + Task { + do { + let entry = try await getEntryForTimeline( + context: context + ) + completion(entry) + } catch { + completion(placeholder(in: context)) + } + } + } + + func getTimeline( + in context: Context, + completion: @escaping (Timeline) -> Void + ) { + Task { + do { + let entry = try await getEntryForTimeline(context: context) + + completion(Timeline(entries: [entry], policy: .never)) + } catch { + completion(Timeline(entries: [], policy: .never)) + } + } + } + + func getEntryForTimeline( + context: Context + ) async throws -> RecentlyPlayedEntry { + let items: [WidgetLibraryItem] + let theme: SimpleTheme + + /// Attempt to fetch from shared defaults, otherwise default to database + if let (widgetItems, widgetTheme) = getItemsFromDefaults() { + items = widgetItems + theme = widgetTheme + } else { + let (widgetItems, widgetTheme) = try await getDataFromDatabase() + items = widgetItems + theme = widgetTheme + } + + let currentlyPlaying = UserDefaults.sharedDefaults.string( + forKey: Constants.UserDefaults.sharedWidgetNowPlayingPath + ) + + return RecentlyPlayedEntry( + date: Date(), + items: items, + currentlyPlaying: currentlyPlaying, + theme: theme + ) + } + + func getDataFromDatabase() async throws -> ([WidgetLibraryItem], SimpleTheme) { + let stack = try await DatabaseInitializer().loadCoreDataStack() + let dataManager = DataManager(coreDataStack: stack) + let libraryService = LibraryService(dataManager: dataManager) + + guard + let lastPlayedItems = libraryService.getLastPlayedItems(limit: 4) + else { + throw BookPlayerError.emptyResponse + } + + let items = lastPlayedItems.map({ + WidgetLibraryItem( + relativePath: $0.relativePath, + title: $0.title, + details: $0.details + ) + }) + + return ( + items, + libraryService.getLibraryCurrentTheme() ?? SimpleTheme.getDefaultTheme() + ) + } + + func getItemsFromDefaults() -> ([WidgetLibraryItem], SimpleTheme)? { + guard + let itemsData = UserDefaults.sharedDefaults.data(forKey: Constants.UserDefaults.sharedWidgetLastPlayedItems), + let items = try? decoder.decode([WidgetLibraryItem].self, from: itemsData) + else { + return nil + } + + let theme: SimpleTheme + if let themeData = UserDefaults.sharedDefaults.data( + forKey: Constants.UserDefaults.sharedWidgetTheme + ), let widgetTheme = try? decoder.decode(SimpleTheme.self, from: themeData) { + theme = widgetTheme + } else { + theme = SimpleTheme.getDefaultTheme() + } + + return (items, theme) + } +} diff --git a/BookPlayerWidgets/Phone/LastPlayed/LastPlayedView.swift b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedView.swift new file mode 100644 index 000000000..48fc4bef8 --- /dev/null +++ b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedView.swift @@ -0,0 +1,107 @@ +// +// LastPlayedView.swift +// BookPlayerWidgetsPhone +// +// Created by Gianni Carlo on 30/9/24. +// Copyright © 2024 Tortuga Power. All rights reserved. +// + +import BookPlayerKit +import SwiftUI +import WidgetKit + +struct LastPlayedModel { + let relativePath: String? + let title: String? + let isPlaying: Bool + let theme: SimpleTheme + + init(item: WidgetLibraryItem?, isPlaying: Bool, theme: SimpleTheme) { + self.relativePath = item?.relativePath + self.title = item?.title + self.isPlaying = isPlaying + self.theme = theme + } +} + +struct LastPlayedView: View { + @Environment(\.colorScheme) var colorScheme + var model: LastPlayedModel + + func getArtworkView(for relativePath: String) -> some View { + ZStack { + Image( + uiImage: UIImage(contentsOfFile: ArtworkService.getCachedImageURL(for: relativePath).path) + ?? ArtworkService.generateDefaultArtwork(from: model.theme.linkColor)! + ) + .resizable() + .frame(width: 90, height: 90) + .aspectRatio(1.0, contentMode: .fit) + .cornerRadius(8.0) + } + } + + var body: some View { + let titleLabel = model.title ?? "---" + + let widgetColors = WidgetUtils.getColors(from: model.theme, with: colorScheme) + + let imageName = model.isPlaying ? "pause.fill" : "play.fill" + + let appIconName = WidgetUtils.getAppIconName() + + return VStack(alignment: .leading) { + if let relativePath = model.relativePath { + HStack { + if #available(iOSApplicationExtension 17.0, iOS 17.0, *) { + Button(intent: BookPlaybackToggleIntent(relativePath: relativePath)) { + ZStack { + getArtworkView(for: relativePath) + Circle() + .foregroundColor(.white) + .frame(width: 30, height: 30) + .opacity(0.8) + Image(systemName: imageName) + .resizable() + .aspectRatio(contentMode: .fit) + .foregroundColor(.black) + .frame(width: 11, height: 11) + .offset(x: 1) + } + } + .buttonStyle(.plain) + } else { + getArtworkView(for: relativePath) + } + + VStack { + Image(appIconName) + .accessibility(hidden: true) + .frame(width: 32, height: 32) + .padding([.trailing], 10) + .cornerRadius(8.0) + Spacer() + } + } + .frame(height: 90) + .padding([.leading]) + .padding([.top], 8) + .accessibility(label: Text("Last Played Book, \(titleLabel)")) + VStack(alignment: .leading) { + Text(titleLabel) + .fontWeight(.semibold) + .foregroundColor(widgetColors.primaryColor) + .font(.footnote) + .lineLimit(2) + .accessibility(hidden: true) + } + .frame(height: 40) + .padding([.leading, .trailing], 15) + } else { + Image(.logoNobackground) + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .widgetBackground(backgroundView: widgetColors.backgroundColor) + } +} diff --git a/BookPlayerWidgets/Phone/LastPlayed/LastPlayedWidgetView.swift b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedWidgetView.swift new file mode 100644 index 000000000..97bc723fe --- /dev/null +++ b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedWidgetView.swift @@ -0,0 +1,50 @@ +// +// LastPlayedWidgetView.swift +// BookPlayerWidgetUIExtension +// +// Created by Gianni Carlo on 24/11/20. +// Copyright © 2020 Tortuga Power. All rights reserved. +// + +import BookPlayerKit +import SwiftUI +import WidgetKit + +struct LastPlayedWidgetView: View { + @Environment(\.colorScheme) var colorScheme + @Environment(\.widgetFamily) var widgetFamily + var entry: LastPlayedProvider.Entry + + var body: some View { + switch widgetFamily { + case .systemMedium: + EmptyView() + default: + LastPlayedView( + model: .init( + item: entry.items.first, + isPlaying: entry.items.first?.relativePath == entry.currentlyPlaying, + theme: entry.theme + ) + ) + } + } +} + +struct LastPlayedWidget: Widget { + let kind: String = Constants.Widgets.lastPlayedWidget.rawValue + + var body: some WidgetConfiguration { + StaticConfiguration( + kind: kind, + provider: LastPlayedProvider(), + content: { entry in + LastPlayedWidgetView(entry: entry) + } + ) + .configurationDisplayName("Last Played Book") + .description("See and play your last played book") + .supportedFamilies([.systemSmall, .systemMedium]) + .contentMarginsDisabledIfAvailable() + } +} diff --git a/BookPlayerWidgets/Phone/LastPlayedWidgetView.swift b/BookPlayerWidgets/Phone/LastPlayedWidgetView.swift deleted file mode 100644 index de7025e8a..000000000 --- a/BookPlayerWidgets/Phone/LastPlayedWidgetView.swift +++ /dev/null @@ -1,219 +0,0 @@ -// -// LastPlayedWidgetView.swift -// BookPlayerWidgetUIExtension -// -// Created by Gianni Carlo on 24/11/20. -// Copyright © 2020 Tortuga Power. All rights reserved. -// - -import BookPlayerKit -import SwiftUI -import WidgetKit - -struct LastPlayedProvider: TimelineProvider { - typealias Entry = SimpleEntry - - func placeholder(in context: Context) -> SimpleEntry { - SimpleEntry( - date: Date(), - title: "Last played book title", - relativePath: nil - ) - } - - func getSnapshot( - in context: Context, - completion: @escaping (Entry) -> Void - ) { - Task { - do { - let entry = try await getEntryForTimeline( - context: context - ) - completion(entry) - } catch { - completion(placeholder(in: context)) - } - } - } - - func getTimeline( - in context: Context, - completion: @escaping (Timeline) -> Void - ) { - Task { - do { - let entry = try await getEntryForTimeline(context: context) - - completion(Timeline(entries: [entry], policy: .never)) - } catch { - completion(Timeline(entries: [], policy: .never)) - } - } - } - - func getEntryForTimeline( - context: Context - ) async throws -> SimpleEntry { - let stack = try await DatabaseInitializer().loadCoreDataStack() - let dataManager = DataManager(coreDataStack: stack) - let libraryService = LibraryService(dataManager: dataManager) - - guard - let lastPlayedItem = libraryService.getLastPlayedItems(limit: 1)?.first - else { - throw BookPlayerError.emptyResponse - } - - let isPlaying = UserDefaults.sharedDefaults.bool( - forKey: Constants.UserDefaults.sharedWidgetIsPlaying - ) - - let theme = libraryService.getLibraryCurrentTheme() ?? SimpleTheme.getDefaultTheme() - - let entry = SimpleEntry( - date: Date(), - title: lastPlayedItem.title, - relativePath: lastPlayedItem.relativePath, - theme: theme, - isPlaying: isPlaying - ) - - return entry - } -} - -struct LastPlayedWidgetView: View { - @Environment(\.colorScheme) var colorScheme - var entry: LastPlayedProvider.Entry - - func getArtworkView(for relativePath: String) -> some View { - ZStack { - Image(uiImage: UIImage(contentsOfFile: ArtworkService.getCachedImageURL(for: relativePath).path) - ?? ArtworkService.generateDefaultArtwork(from: entry.theme.linkColor)!) - .resizable() - .frame(width: 90, height: 90) - .aspectRatio(1.0, contentMode: .fit) - .cornerRadius(8.0) - } - } - - var body: some View { - let titleLabel = entry.title ?? "---" - - let widgetColors = WidgetUtils.getColors(from: entry.theme, with: colorScheme) - - let imageName = entry.isPlaying ? "pause.fill" : "play.fill" - - let appIconName = WidgetUtils.getAppIconName() - - return VStack(alignment: .leading) { - HStack { - if let relativePath = entry.relativePath { - if #available(iOSApplicationExtension 17.0, iOS 17.0, *) { - Button(intent: BookPlaybackToggleIntent(relativePath: relativePath)) { - ZStack { - getArtworkView(for: relativePath) - Circle() - .foregroundColor(.white) - .frame(width: 30, height: 30) - .opacity(0.8) - Image(systemName: imageName) - .resizable() - .aspectRatio(contentMode: .fit) - .foregroundColor(.black) - .frame(width: 11, height: 11) - .offset(x: 1) - } - } - .buttonStyle(.plain) - } else { - getArtworkView(for: relativePath) - } - } else { - Rectangle() - .fill(Color.secondary) - .frame(width: 90, height: 90) - .aspectRatio(1.0, contentMode: .fit) - .cornerRadius(8.0) - } - - VStack { - Image(appIconName) - .accessibility(hidden: true) - .frame(width: 32, height: 32) - .padding([.trailing], 10) - .cornerRadius(8.0) - Spacer() - } - } - .frame(height: 90) - .padding([.leading]) - .padding([.top], 8) - .accessibility(label: Text("Last Played Book, \(titleLabel)")) - VStack(alignment: .leading) { - Text(titleLabel) - .fontWeight(.semibold) - .foregroundColor(widgetColors.primaryColor) - .font(.footnote) - .lineLimit(2) - .accessibility(hidden: true) - } - .frame(height: 40) - .padding([.leading, .trailing], 15) - } - .frame(maxWidth: .infinity, maxHeight: .infinity) - .widgetBackground(backgroundView: widgetColors.backgroundColor) - } -} - -struct LastPlayedWidgetView_Previews: PreviewProvider { - static var previews: some View { - Group { - LastPlayedWidgetView(entry: SimpleEntry( - date: Date(), - title: "Test Book Title", - relativePath: nil - )) - .previewContext(WidgetPreviewContext(family: .systemSmall)) - LastPlayedWidgetView(entry: SimpleEntry( - date: Date(), - title: nil, - relativePath: nil - )) - .previewContext(WidgetPreviewContext(family: .systemSmall)) - LastPlayedWidgetView(entry: SimpleEntry( - date: Date(), - title: "Test Book Title", - relativePath: nil - )) - .previewContext(WidgetPreviewContext(family: .systemSmall)) - .environment(\.colorScheme, .dark) - LastPlayedWidgetView(entry: SimpleEntry( - date: Date(), - title: nil, - relativePath: nil - )) - .previewContext(WidgetPreviewContext(family: .systemSmall)) - .environment(\.colorScheme, .dark) - } - } -} - -struct LastPlayedWidget: Widget { - let kind: String = Constants.Widgets.lastPlayedWidget.rawValue - - var body: some WidgetConfiguration { - StaticConfiguration( - kind: kind, - provider: LastPlayedProvider(), - content: { entry in - LastPlayedWidgetView(entry: entry) - } - ) - .configurationDisplayName("Last Played Book") - .description("See and play your last played book") - .supportedFamilies([.systemSmall]) - .contentMarginsDisabledIfAvailable() - } -} diff --git a/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksProvider.swift b/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksProvider.swift new file mode 100644 index 000000000..ec7ff78fa --- /dev/null +++ b/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksProvider.swift @@ -0,0 +1,82 @@ +// +// RecentBooksProvider.swift +// BookPlayerWidgetsPhone +// +// Created by Gianni Carlo on 30/9/24. +// Copyright © 2024 Tortuga Power. All rights reserved. +// + +import BookPlayerKit +import SwiftUI +import WidgetKit + +struct RecentBooksProvider: TimelineProvider { + let numberOfBooks = 4 + + typealias Entry = LibraryEntry + + func placeholder(in context: Context) -> LibraryEntry { + return LibraryEntry( + date: Date(), + items: [ + SimpleLibraryItem.previewItem(title: "Last played"), + SimpleLibraryItem.previewItem(title: "Book title"), + SimpleLibraryItem.previewItem(title: "Book title"), + SimpleLibraryItem.previewItem(title: "Book title"), + ] + ) + } + + func getSnapshot( + in context: Context, + completion: @escaping (LibraryEntry) -> Void + ) { + Task { + do { + let entry = try await getEntryForTimeline( + context: context + ) + completion(entry) + } catch { + completion(placeholder(in: context)) + } + } + } + + func getTimeline( + in context: Context, + completion: @escaping (Timeline) -> Void + ) { + Task { + do { + let entry = try await getEntryForTimeline(context: context) + + completion(Timeline(entries: [entry], policy: .never)) + } catch { + completion(Timeline(entries: [], policy: .never)) + } + } + } + + func getEntryForTimeline(context: Context) async throws -> LibraryEntry { + let stack = try await DatabaseInitializer().loadCoreDataStack() + let dataManager = DataManager(coreDataStack: stack) + let libraryService = LibraryService(dataManager: dataManager) + + guard + let items = libraryService.getLastPlayedItems(limit: numberOfBooks) + else { + throw BookPlayerError.emptyResponse + } + + let theme = libraryService.getLibraryCurrentTheme() ?? SimpleTheme.getDefaultTheme() + + let entry = LibraryEntry( + date: Date(), + items: items, + theme: theme + ) + + return entry + } +} diff --git a/BookPlayerWidgets/Phone/RecentBooksWidgetView.swift b/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksWidgetView.swift similarity index 63% rename from BookPlayerWidgets/Phone/RecentBooksWidgetView.swift rename to BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksWidgetView.swift index 5dcad9e52..b07cbc090 100644 --- a/BookPlayerWidgets/Phone/RecentBooksWidgetView.swift +++ b/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksWidgetView.swift @@ -10,77 +10,6 @@ import BookPlayerKit import SwiftUI import WidgetKit -struct RecentBooksProvider: TimelineProvider { - let numberOfBooks = 4 - - typealias Entry = LibraryEntry - - func placeholder(in context: Context) -> LibraryEntry { - return LibraryEntry( - date: Date(), - items: [ - SimpleLibraryItem.previewItem(title: "Last played"), - SimpleLibraryItem.previewItem(title: "Book title"), - SimpleLibraryItem.previewItem(title: "Book title"), - SimpleLibraryItem.previewItem(title: "Book title") - ] - ) - } - - func getSnapshot( - in context: Context, - completion: @escaping (LibraryEntry) -> Void - ) { - Task { - do { - let entry = try await getEntryForTimeline( - context: context - ) - completion(entry) - } catch { - completion(placeholder(in: context)) - } - } - } - - func getTimeline( - in context: Context, - completion: @escaping (Timeline) -> Void - ) { - Task { - do { - let entry = try await getEntryForTimeline(context: context) - - completion(Timeline(entries: [entry], policy: .never)) - } catch { - completion(Timeline(entries: [], policy: .never)) - } - } - } - - func getEntryForTimeline(context: Context) async throws -> LibraryEntry { - let stack = try await DatabaseInitializer().loadCoreDataStack() - let dataManager = DataManager(coreDataStack: stack) - let libraryService = LibraryService(dataManager: dataManager) - - guard - let items = libraryService.getLastPlayedItems(limit: numberOfBooks) - else { - throw BookPlayerError.emptyResponse - } - - let theme = libraryService.getLibraryCurrentTheme() ?? SimpleTheme.getDefaultTheme() - - let entry = LibraryEntry( - date: Date(), - items: items, - theme: theme - ) - - return entry - } -} - struct BookView: View { var item: SimpleLibraryItem var titleColor: Color @@ -94,8 +23,10 @@ struct BookView: View { let cachedImageURL = ArtworkService.getCachedImageURL(for: identifier) return VStack(spacing: 5) { - Image(uiImage: UIImage(contentsOfFile: cachedImageURL.path) - ?? ArtworkService.generateDefaultArtwork(from: entry.theme.linkColor)!) + Image( + uiImage: UIImage(contentsOfFile: cachedImageURL.path) + ?? ArtworkService.generateDefaultArtwork(from: entry.theme.linkColor)! + ) .resizable() .frame(minWidth: 60, maxWidth: 60, minHeight: 60, maxHeight: 60) .aspectRatio(1.0, contentMode: .fit) @@ -175,14 +106,17 @@ struct RecentBooksWidgetView: View { struct RecentBooksWidgetView_Previews: PreviewProvider { static var previews: some View { Group { - RecentBooksWidgetView(entry: LibraryEntry( - date: Date(), - items: [ - .previewItem(title: "a very very very long title"), - .previewItem(title: "a short title"), - .previewItem(title: "a short title"), - .previewItem(title: "a short title") - ])) + RecentBooksWidgetView( + entry: LibraryEntry( + date: Date(), + items: [ + .previewItem(title: "a very very very long title"), + .previewItem(title: "a short title"), + .previewItem(title: "a short title"), + .previewItem(title: "a short title"), + ] + ) + ) .previewContext(WidgetPreviewContext(family: .systemMedium)) } } @@ -224,6 +158,7 @@ extension SimpleLibraryItem { parentFolder: nil, originalFileName: "", lastPlayDate: nil, - type: SimpleItemType.book) + type: SimpleItemType.book + ) } } diff --git a/BookPlayerWidgets/Phone/WidgetEntries.swift b/BookPlayerWidgets/Phone/WidgetEntries.swift index 3f7c8d50e..ce26d3f1a 100644 --- a/BookPlayerWidgets/Phone/WidgetEntries.swift +++ b/BookPlayerWidgets/Phone/WidgetEntries.swift @@ -6,9 +6,9 @@ // Copyright © 2023 Tortuga Power. All rights reserved. // +import BookPlayerKit import Foundation import WidgetKit -import BookPlayerKit struct SimpleEntry: TimelineEntry { let date: Date @@ -69,6 +69,36 @@ struct LibraryEntry: TimelineEntry { } } +struct RecentlyPlayedEntry: TimelineEntry { + let date: Date + let items: [WidgetLibraryItem] + let currentlyPlaying: String? + let theme: SimpleTheme + + init( + date: Date, + items: [WidgetLibraryItem], + currentlyPlaying: String?, + theme: SimpleTheme + ) { + self.date = date + self.items = items + self.currentlyPlaying = currentlyPlaying + self.theme = theme + } + + init( + date: Date, + items: [WidgetLibraryItem], + currentlyPlaying: String? + ) { + self.date = date + self.items = items + self.currentlyPlaying = currentlyPlaying + self.theme = SimpleTheme.getDefaultTheme() + } +} + struct TimeListenedEntry: TimelineEntry { let date: Date let title: String? diff --git a/Shared/Constants.swift b/Shared/Constants.swift index d3a71ea40..7a6b7c051 100644 --- a/Shared/Constants.swift +++ b/Shared/Constants.swift @@ -53,8 +53,14 @@ public enum Constants { /// Shared widget action URL public static let sharedWidgetActionURL = "sharedWidgetActionURL" - /// Shared widget isPlaying state - public static let sharedWidgetIsPlaying = "sharedWidgetIsPlaying" + /// Shared widget currently playing relative path + public static let sharedWidgetNowPlayingPath = "sharedWidgetNowPlayingPath" + + /// Key to store the last played items + public static let sharedWidgetLastPlayedItems = "sharedWidgetLastPlayedItems" + + /// Key to store the current theme + public static let sharedWidgetTheme = "sharedWidgetTheme" } public enum SmartRewind { diff --git a/Shared/CoreData/Lightweight-Models/WidgetLibraryItem.swift b/Shared/CoreData/Lightweight-Models/WidgetLibraryItem.swift new file mode 100644 index 000000000..b8190ef8d --- /dev/null +++ b/Shared/CoreData/Lightweight-Models/WidgetLibraryItem.swift @@ -0,0 +1,25 @@ +// +// WidgetLibraryItem.swift +// BookPlayerWidgetsPhone +// +// Created by Gianni Carlo on 30/9/24. +// Copyright © 2024 Tortuga Power. All rights reserved. +// + +import Foundation + +public struct WidgetLibraryItem: Codable { + public let relativePath: String + public let title: String + public let details: String? + + public init( + relativePath: String, + title: String, + details: String? = nil + ) { + self.relativePath = relativePath + self.title = title + self.details = details + } +} From 1fed5e4a8fef7eb16d475f30a340ff8fcf95a503 Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Tue, 1 Oct 2024 13:37:25 -0500 Subject: [PATCH 07/18] Rework recent books widget to use same provider as last played --- BookPlayer.xcodeproj/project.pbxproj | 8 +-- BookPlayer/Services/ActionParserService.swift | 40 ++++++++---- BookPlayerWidgets/BookPlayerWidgets.swift | 1 - .../Phone/LastPlayed/LastPlayedModel.swift | 24 +++++++ .../Phone/LastPlayed/LastPlayedView.swift | 16 +---- .../LastPlayed/LastPlayedWidgetView.swift | 6 +- .../Deprecated/RecentBooksWidgetView.swift | 65 +++++++++---------- Shared/CommandParser.swift | 19 ++++-- 8 files changed, 105 insertions(+), 74 deletions(-) create mode 100644 BookPlayerWidgets/Phone/LastPlayed/LastPlayedModel.swift diff --git a/BookPlayer.xcodeproj/project.pbxproj b/BookPlayer.xcodeproj/project.pbxproj index f6539401d..869b4bf43 100644 --- a/BookPlayer.xcodeproj/project.pbxproj +++ b/BookPlayer.xcodeproj/project.pbxproj @@ -388,7 +388,7 @@ 639720752CAAFB010045A4DB /* WidgetLibraryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720732CAAFB010045A4DB /* WidgetLibraryItem.swift */; }; 639720832CAB0C380045A4DB /* LastPlayedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720822CAB0C380045A4DB /* LastPlayedView.swift */; }; 639720852CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */; }; - 639720862CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */; }; + 6397208A2CAC5C870045A4DB /* LastPlayedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720892CAC5C870045A4DB /* LastPlayedModel.swift */; }; 6399F94D2AA03C6C00A5C8EA /* BPSKANManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */; }; 639AC9892AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; 639AC98A2AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; @@ -417,7 +417,6 @@ 63B760FC2C33B77F00AA98C7 /* SupportProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B760FB2C33B77F00AA98C7 /* SupportProfileView.swift */; }; 63C1A8AF2B09158600C4B418 /* BookStartPlaybackIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 634E67432AFB2DF500595BAC /* BookStartPlaybackIntent.swift */; }; 63C1A8B02B0915EE00C4B418 /* WidgetUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 418445C2258AE11E0072DD13 /* WidgetUtils.swift */; }; - 63C1A8B12B09165400C4B418 /* RecentBooksWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41ADD6D92570AC6300660C64 /* RecentBooksWidgetView.swift */; }; 63C1A8B22B09166F00C4B418 /* WidgetEntries.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637DAB092AEB3E0D006DC2D1 /* WidgetEntries.swift */; }; 63C6C2E62B5029BC00FFE0D8 /* SettingsAutolockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C6C2E52B5029BC00FFE0D8 /* SettingsAutolockView.swift */; }; 63C6C2E82B5029FE00FFE0D8 /* SettingsAutolockViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C6C2E72B5029FE00FFE0D8 /* SettingsAutolockViewModel.swift */; }; @@ -1170,6 +1169,7 @@ 639720732CAAFB010045A4DB /* WidgetLibraryItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetLibraryItem.swift; sourceTree = ""; }; 639720822CAB0C380045A4DB /* LastPlayedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedView.swift; sourceTree = ""; }; 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentBooksProvider.swift; sourceTree = ""; }; + 639720892CAC5C870045A4DB /* LastPlayedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedModel.swift; sourceTree = ""; }; 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPSKANManager.swift; sourceTree = ""; }; 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPDownloadURLSession.swift; sourceTree = ""; }; 639E12C52B85AACF00C875F7 /* SyncTasksObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTasksObject.swift; sourceTree = ""; }; @@ -2236,6 +2236,7 @@ children = ( 417D9993256DE3FB00C3B753 /* LastPlayedWidgetView.swift */, 639720822CAB0C380045A4DB /* LastPlayedView.swift */, + 639720892CAC5C870045A4DB /* LastPlayedModel.swift */, 639720712CAAF8290045A4DB /* LastPlayedProvider.swift */, ); path = LastPlayed; @@ -3455,6 +3456,7 @@ 630826062AF525F1002ACE0D /* SharedWidgetContainerView.swift in Sources */, 4106414925872699008EB8D0 /* TimeListenedSmallView.swift in Sources */, 417D996F256D73B400C3B753 /* Intents.intentdefinition in Sources */, + 6397208A2CAC5C870045A4DB /* LastPlayedModel.swift in Sources */, 417D9994256DE3FB00C3B753 /* LastPlayedWidgetView.swift in Sources */, 41A359C7276232E00020D5F5 /* MappingModel_v7_to_v8.xcmappingmodel in Sources */, 416A29AA2569658100605395 /* BookPlayerWidgets.swift in Sources */, @@ -3629,7 +3631,6 @@ 9F5FBB08293EDCD8009F4B0E /* ItemDetailsViewController.swift in Sources */, 634BA5AD2C180F5E0015314D /* StoryViewModel.swift in Sources */, 9F2681B628898A7300359BD3 /* LoginDisclaimerView.swift in Sources */, - 63C1A8B12B09165400C4B418 /* RecentBooksWidgetView.swift in Sources */, 9FD8D95829DC53750074C2D8 /* CoreServices.swift in Sources */, 9F4691F22800D58A00A8F0E8 /* CompleteAccountCoordinator.swift in Sources */, 9F00A5F6294F793F005EA316 /* ItemDetailsView.swift in Sources */, @@ -3675,7 +3676,6 @@ 41188D2A26ED4D8E0017124E /* ItemListViewModel.swift in Sources */, C398559C20C492FF00BE9EC0 /* AddButton.swift in Sources */, 9F89D89C27EDFCA400F73947 /* SceneDelegate.swift in Sources */, - 639720862CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */, 9F3D0CE928C2BFC600E9E8A3 /* ButtonFreeCoordinator.swift in Sources */, 416AAC3323F51031005AD04F /* LocalizableButton.swift in Sources */, 63B50F052B692E4200BCABBA /* ListSyncRefreshService.swift in Sources */, diff --git a/BookPlayer/Services/ActionParserService.swift b/BookPlayer/Services/ActionParserService.swift index 5ba5f1dd3..8acb45742 100644 --- a/BookPlayer/Services/ActionParserService.swift +++ b/BookPlayer/Services/ActionParserService.swift @@ -83,7 +83,8 @@ class ActionParserService { } if let valueString = action.getQueryValue(for: "interval"), - let interval = Double(valueString) { + let interval = Double(valueString) + { playerManager.skip(-interval) } else { playerManager.rewind() @@ -98,7 +99,8 @@ class ActionParserService { } if let valueString = action.getQueryValue(for: "interval"), - let interval = Double(valueString) { + let interval = Double(valueString) + { playerManager.skip(interval) } else { playerManager.forward() @@ -169,7 +171,8 @@ class ActionParserService { private class func handleSleepAction(_ action: Action) { guard let value = action.getQueryValue(for: "seconds"), - let seconds = Double(value) else { + let seconds = Double(value) + else { return } @@ -190,8 +193,17 @@ class ActionParserService { return } - self.removeAction(action) - playerManager.playPause() + if let bookIdentifier = action.getQueryValue(for: "identifier"), + playerManager.currentItem?.relativePath != bookIdentifier + { + if let libraryCoordinator = AppDelegate.shared?.activeSceneDelegate?.mainCoordinator?.getLibraryCoordinator() { + self.removeAction(action) + libraryCoordinator.loadPlayer(bookIdentifier) + } + } else { + self.removeAction(action) + playerManager.playPause() + } } private class func handlePauseAction(_ action: Action) { @@ -213,14 +225,16 @@ class ActionParserService { } if let value = action.getQueryValue(for: "showPlayer"), - let showPlayer = Bool(value), - showPlayer { + let showPlayer = Bool(value), + showPlayer + { AppDelegate.shared?.showPlayer() } if let value = action.getQueryValue(for: "autoplay"), - let autoplay = Bool(value), - !autoplay { + let autoplay = Bool(value), + !autoplay + { return } @@ -231,7 +245,8 @@ class ActionParserService { } if let loadedItem = playerManager.currentItem, - loadedItem.relativePath == bookIdentifier { + loadedItem.relativePath == bookIdentifier + { self.removeAction(action) playerManager.play() return @@ -254,7 +269,10 @@ class ActionParserService { } guard let url = URL(string: urlString) else { - libraryCoordinator.showAlert("error_title".localized, message: String.localizedStringWithFormat("invalid_url_title".localized, urlString)) + libraryCoordinator.showAlert( + "error_title".localized, + message: String.localizedStringWithFormat("invalid_url_title".localized, urlString) + ) return } diff --git a/BookPlayerWidgets/BookPlayerWidgets.swift b/BookPlayerWidgets/BookPlayerWidgets.swift index 06b2e8770..64dd83d27 100644 --- a/BookPlayerWidgets/BookPlayerWidgets.swift +++ b/BookPlayerWidgets/BookPlayerWidgets.swift @@ -37,7 +37,6 @@ struct BookPlayerBundle: WidgetBundle { var body: some Widget { #if os(iOS) LastPlayedWidget() - RecentBooksWidget() TimeListenedWidget() if #available(iOSApplicationExtension 16.1, *) { SharedWidget() diff --git a/BookPlayerWidgets/Phone/LastPlayed/LastPlayedModel.swift b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedModel.swift new file mode 100644 index 000000000..4a00b2544 --- /dev/null +++ b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedModel.swift @@ -0,0 +1,24 @@ +// +// LastPlayedModel.swift +// BookPlayerWidgetsPhone +// +// Created by Gianni Carlo on 1/10/24. +// Copyright © 2024 Tortuga Power. All rights reserved. +// + +import BookPlayerKit +import Foundation + +struct LastPlayedModel { + let relativePath: String? + let title: String? + let isPlaying: Bool + let theme: SimpleTheme + + init(item: WidgetLibraryItem?, isPlaying: Bool, theme: SimpleTheme) { + self.relativePath = item?.relativePath + self.title = item?.title + self.isPlaying = isPlaying + self.theme = theme + } +} diff --git a/BookPlayerWidgets/Phone/LastPlayed/LastPlayedView.swift b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedView.swift index 48fc4bef8..e3151532a 100644 --- a/BookPlayerWidgets/Phone/LastPlayed/LastPlayedView.swift +++ b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedView.swift @@ -10,20 +10,6 @@ import BookPlayerKit import SwiftUI import WidgetKit -struct LastPlayedModel { - let relativePath: String? - let title: String? - let isPlaying: Bool - let theme: SimpleTheme - - init(item: WidgetLibraryItem?, isPlaying: Bool, theme: SimpleTheme) { - self.relativePath = item?.relativePath - self.title = item?.title - self.isPlaying = isPlaying - self.theme = theme - } -} - struct LastPlayedView: View { @Environment(\.colorScheme) var colorScheme var model: LastPlayedModel @@ -66,7 +52,7 @@ struct LastPlayedView: View { .aspectRatio(contentMode: .fit) .foregroundColor(.black) .frame(width: 11, height: 11) - .offset(x: 1) + .offset(x: model.isPlaying ? 0 : 1) } } .buttonStyle(.plain) diff --git a/BookPlayerWidgets/Phone/LastPlayed/LastPlayedWidgetView.swift b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedWidgetView.swift index 97bc723fe..c654cb2e4 100644 --- a/BookPlayerWidgets/Phone/LastPlayed/LastPlayedWidgetView.swift +++ b/BookPlayerWidgets/Phone/LastPlayed/LastPlayedWidgetView.swift @@ -18,7 +18,7 @@ struct LastPlayedWidgetView: View { var body: some View { switch widgetFamily { case .systemMedium: - EmptyView() + RecentBooksWidgetView(entry: entry) default: LastPlayedView( model: .init( @@ -42,8 +42,8 @@ struct LastPlayedWidget: Widget { LastPlayedWidgetView(entry: entry) } ) - .configurationDisplayName("Last Played Book") - .description("See and play your last played book") + .configurationDisplayName("Last Played Books") + .description("See and play your last played books") .supportedFamilies([.systemSmall, .systemMedium]) .contentMarginsDisabledIfAvailable() } diff --git a/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksWidgetView.swift b/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksWidgetView.swift index b07cbc090..7368d64e0 100644 --- a/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksWidgetView.swift +++ b/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksWidgetView.swift @@ -11,26 +11,40 @@ import SwiftUI import WidgetKit struct BookView: View { - var item: SimpleLibraryItem + var item: WidgetLibraryItem var titleColor: Color - var theme: SimpleTheme? - var entry: RecentBooksProvider.Entry + var theme: SimpleTheme + var isPlaying: Bool var body: some View { let title = item.title let identifier = item.relativePath + let pauseImage: String? = isPlaying ? "pause.fill" : nil let cachedImageURL = ArtworkService.getCachedImageURL(for: identifier) return VStack(spacing: 5) { - Image( - uiImage: UIImage(contentsOfFile: cachedImageURL.path) - ?? ArtworkService.generateDefaultArtwork(from: entry.theme.linkColor)! - ) - .resizable() - .frame(minWidth: 60, maxWidth: 60, minHeight: 60, maxHeight: 60) - .aspectRatio(1.0, contentMode: .fit) - .cornerRadius(8.0) + ZStack { + Image( + uiImage: UIImage(contentsOfFile: cachedImageURL.path) + ?? ArtworkService.generateDefaultArtwork(from: theme.linkColor)! + ) + .resizable() + .frame(minWidth: 60, maxWidth: 60, minHeight: 60, maxHeight: 60) + .aspectRatio(1.0, contentMode: .fit) + .cornerRadius(8.0) + if let pauseImage { + Circle() + .foregroundColor(.white) + .frame(width: 30, height: 30) + .opacity(0.8) + Image(systemName: pauseImage) + .resizable() + .aspectRatio(contentMode: .fit) + .foregroundColor(.black) + .frame(width: 11, height: 11) + } + } Text(title) .fontWeight(.semibold) @@ -45,7 +59,7 @@ struct BookView: View { struct RecentBooksWidgetView: View { @Environment(\.colorScheme) var colorScheme - var entry: RecentBooksProvider.Entry + var entry: LastPlayedProvider.Entry var body: some View { let items = Array(entry.items.prefix(4)) @@ -73,12 +87,12 @@ struct RecentBooksWidgetView: View { HStack { ForEach(items, id: \.relativePath) { item in if #available(iOSApplicationExtension 17.0, iOS 17.0, *) { - Button(intent: BookStartPlaybackIntent(relativePath: item.relativePath)) { + Button(intent: BookPlaybackToggleIntent(relativePath: item.relativePath)) { BookView( item: item, titleColor: widgetColors.primaryColor, theme: entry.theme, - entry: entry + isPlaying: item.relativePath == entry.currentlyPlaying ) .frame(minWidth: 0, maxWidth: .infinity) } @@ -88,7 +102,7 @@ struct RecentBooksWidgetView: View { item: item, titleColor: widgetColors.primaryColor, theme: entry.theme, - entry: entry + isPlaying: item.relativePath == entry.currentlyPlaying ) .frame(minWidth: 0, maxWidth: .infinity) } @@ -103,32 +117,13 @@ struct RecentBooksWidgetView: View { } } -struct RecentBooksWidgetView_Previews: PreviewProvider { - static var previews: some View { - Group { - RecentBooksWidgetView( - entry: LibraryEntry( - date: Date(), - items: [ - .previewItem(title: "a very very very long title"), - .previewItem(title: "a short title"), - .previewItem(title: "a short title"), - .previewItem(title: "a short title"), - ] - ) - ) - .previewContext(WidgetPreviewContext(family: .systemMedium)) - } - } -} - struct RecentBooksWidget: Widget { let kind: String = "com.bookplayer.widget.medium.recentBooks" var body: some WidgetConfiguration { StaticConfiguration( kind: kind, - provider: RecentBooksProvider(), + provider: LastPlayedProvider(), content: { entry in RecentBooksWidgetView(entry: entry) } diff --git a/Shared/CommandParser.swift b/Shared/CommandParser.swift index 86739ae48..3bb8f0c78 100644 --- a/Shared/CommandParser.swift +++ b/Shared/CommandParser.swift @@ -58,7 +58,8 @@ public class CommandParser { if command == .download { guard let query = url.query, let parameter = query.components(separatedBy: "url=").last else { return nil } - let paramURLstring = parameter.replacingOccurrences(of: "'", with: "").replacingOccurrences(of: "\"", with: "").replacingOccurrences(of: "%22", with: "") + let paramURLstring = parameter.replacingOccurrences(of: "'", with: "").replacingOccurrences(of: "\"", with: "") + .replacingOccurrences(of: "%22", with: "") let queryItem = URLQueryItem(name: "url", value: paramURLstring) @@ -68,7 +69,8 @@ public class CommandParser { var parameters = [URLQueryItem]() if let components = URLComponents(url: url, resolvingAgainstBaseURL: true), - let queryItems = components.queryItems { + let queryItems = components.queryItems + { parameters = queryItems } @@ -77,7 +79,8 @@ public class CommandParser { public class func parse(_ message: [String: Any]) -> Action? { guard let commandString = message["command"] as? String, - let command = Command(rawValue: commandString) else { return nil } + let command = Command(rawValue: commandString) + else { return nil } var dictionary = message dictionary.removeValue(forKey: "command") @@ -258,7 +261,10 @@ public class TimeParser { return durationFormatter.string(from: time)! } - public class func formatDuration(_ duration: TimeInterval, unitsStyle: DateComponentsFormatter.UnitsStyle = .short) -> String { + public class func formatDuration( + _ duration: TimeInterval, + unitsStyle: DateComponentsFormatter.UnitsStyle = .short + ) -> String { let durationFormatter = DateComponentsFormatter() durationFormatter.unitsStyle = unitsStyle @@ -268,7 +274,10 @@ public class TimeParser { return durationFormatter.string(from: duration)! } - public class func formatTotalDuration(_ duration: TimeInterval, allowedUnits: NSCalendar.Unit = [.hour, .minute, .second]) -> String { + public class func formatTotalDuration( + _ duration: TimeInterval, + allowedUnits: NSCalendar.Unit = [.hour, .minute, .second] + ) -> String { let durationFormatter = DateComponentsFormatter() durationFormatter.unitsStyle = .abbreviated From aecf1cf87dc03a8eb7e7be5c8ad747e20dadf785 Mon Sep 17 00:00:00 2001 From: Bruno <147919252+wu0lss4j@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:32:29 +0200 Subject: [PATCH 08/18] Update Localizable.strings some pt-pt grammar mistakes and removing pt-br translations --- BookPlayer/pt-PT.lproj/Localizable.strings | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/BookPlayer/pt-PT.lproj/Localizable.strings b/BookPlayer/pt-PT.lproj/Localizable.strings index 4981c5e1c..df86cbc1a 100644 --- a/BookPlayer/pt-PT.lproj/Localizable.strings +++ b/BookPlayer/pt-PT.lproj/Localizable.strings @@ -292,23 +292,23 @@ "settings_skan_attribution_title" = "Desativar a atribuição SKAN"; "settings_skan_attribution_description" = "SKAN é uma solução de atribuição prioritária de privacidade da Apple e permite medir a eficácia de uma campanha sem comprometer a privacidade do utilizador"; "intent_sleeptimer_cancel" = "Cancelar o Temporizador"; -"intent_sleeptimer_set_duration" = "Definir duranção no Temporizador"; +"intent_sleeptimer_set_duration" = "Definir duração no Temporizador"; "duration_title" = "Duração"; "intent_sleeptimer_request_duration_title" = "Durante quanto tempo"; "Set Sleep Timer for ${duration}" = "Definir Temporização durante ${duration}"; "intent_sleeptimer_eoc_title" = "Definir Temporização no Final do Capítulo"; -"intent_lastbook_play_title" = "Continuar o último livro reproduzido"; -"intent_lastbook_empty_error" = "Último livro reproduzido não encontrado"; +"intent_lastbook_play_title" = "Continuar o último audiolivro reproduzido"; +"intent_lastbook_empty_error" = "Último audiolivro reproduzido não encontrado"; "intent_playback_pause_title" = "Pausar reprodução"; -"storage_artwork_cache_title" = "Tamanho do cache de arte"; -"settings_share_debug_information" = "Compartilhe informações de depuração"; +"storage_artwork_cache_title" = "Tamanho do cache de imagens"; +"settings_share_debug_information" = "Partilhar informações de depuração"; "settings_autlock_section_title" = "Bloqueio automático"; "settings_sleeptimer_auto_title" = "Temporizador automático"; -"settings_sleeptimer_auto_description" = "Reinicie o último temporizador ativo quando a reprodução for retomada"; -"sync_tasks_inprogress_alert_title" = "Não é possível sincronizar dados enquanto há tarefas na fila em andamento"; +"settings_sleeptimer_auto_description" = "Reinicie o último temporizador activo quando a reprodução for retomada"; +"sync_tasks_inprogress_alert_title" = "Não é possível sincronizar dados enquanto há tarefas na fila de espera"; "sync_tasks_view_title" = "Ver tarefas"; -"settings_datausage_title" = "Uso de dados"; -"datausage_upload_wifionly_title" = "Fazer upload usando dados de celular"; +"settings_datausage_title" = "Utilização de dados"; +"datausage_upload_wifionly_title" = "Utilizar dados móveis para fazer upload"; "warning_title" = "Aviso"; "sync_tasks_item_upload_queued" = "Há uma tarefa de upload na fila para: \n %@ \n A remoção do arquivo impedirá que o aplicativo o carregue"; "intent_custom_skipforward_title" = "Avançar com intervalo"; From d668cba41a6cc60d98cda1da89fd0847c3363da1 Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Wed, 2 Oct 2024 12:56:07 -0500 Subject: [PATCH 09/18] Add launch button for control center --- BookPlayer.xcodeproj/project.pbxproj | 6 ++ .../bookplayer.icon.symbolset/Contents.json | 12 +++ .../bookplayer.icon.svg | 94 +++++++++++++++++++ BookPlayerWidgets/BookPlayerWidgets.swift | 56 ++++++----- .../Phone/LaunchAppControlWidgetView.swift | 43 +++++++++ 5 files changed, 186 insertions(+), 25 deletions(-) create mode 100644 BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/Contents.json create mode 100644 BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/bookplayer.icon.svg create mode 100644 BookPlayerWidgets/Phone/LaunchAppControlWidgetView.swift diff --git a/BookPlayer.xcodeproj/project.pbxproj b/BookPlayer.xcodeproj/project.pbxproj index 869b4bf43..e858a1380 100644 --- a/BookPlayer.xcodeproj/project.pbxproj +++ b/BookPlayer.xcodeproj/project.pbxproj @@ -389,6 +389,8 @@ 639720832CAB0C380045A4DB /* LastPlayedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720822CAB0C380045A4DB /* LastPlayedView.swift */; }; 639720852CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */; }; 6397208A2CAC5C870045A4DB /* LastPlayedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720892CAC5C870045A4DB /* LastPlayedModel.swift */; }; + 6397208C2CAC95040045A4DB /* LaunchAppControlWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6397208B2CAC95040045A4DB /* LaunchAppControlWidgetView.swift */; }; + 6397208D2CAC95040045A4DB /* LaunchAppControlWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6397208B2CAC95040045A4DB /* LaunchAppControlWidgetView.swift */; }; 6399F94D2AA03C6C00A5C8EA /* BPSKANManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */; }; 639AC9892AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; 639AC98A2AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; @@ -1170,6 +1172,7 @@ 639720822CAB0C380045A4DB /* LastPlayedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedView.swift; sourceTree = ""; }; 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentBooksProvider.swift; sourceTree = ""; }; 639720892CAC5C870045A4DB /* LastPlayedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedModel.swift; sourceTree = ""; }; + 6397208B2CAC95040045A4DB /* LaunchAppControlWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchAppControlWidgetView.swift; sourceTree = ""; }; 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPSKANManager.swift; sourceTree = ""; }; 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPDownloadURLSession.swift; sourceTree = ""; }; 639E12C52B85AACF00C875F7 /* SyncTasksObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTasksObject.swift; sourceTree = ""; }; @@ -2302,6 +2305,7 @@ children = ( 634E67432AFB2DF500595BAC /* BookStartPlaybackIntent.swift */, 6309F1252B0CF1C1002B86A4 /* BookPlaybackToggleIntent.swift */, + 6397208B2CAC95040045A4DB /* LaunchAppControlWidgetView.swift */, 4106413E258725F1008EB8D0 /* TimeListened */, 637DAB092AEB3E0D006DC2D1 /* WidgetEntries.swift */, 418445C2258AE11E0072DD13 /* WidgetUtils.swift */, @@ -3465,6 +3469,7 @@ 410641282579AA2F008EB8D0 /* TimeListenedWidgetView.swift in Sources */, 6309F1272B0CF658002B86A4 /* BookPlaybackToggleIntent.swift in Sources */, 630826032AF5225F002ACE0D /* CircularView.swift in Sources */, + 6397208C2CAC95040045A4DB /* LaunchAppControlWidgetView.swift in Sources */, 630826042AF522EA002ACE0D /* SharedWidgetEntry.swift in Sources */, 41064152258726D2008EB8D0 /* TimeListenedMediumView.swift in Sources */, 41C3396A25E04112003ED2B0 /* MappingModel_v2_to_v3.xcmappingmodel in Sources */, @@ -3640,6 +3645,7 @@ 9F5F13682978D9E100F061A0 /* ProfileSyncTasksStatusView.swift in Sources */, 41AD3DA7221C850F00DC41E1 /* IconCellView.swift in Sources */, 9FF710B92A213084006490E0 /* QueuedSyncTaskRowView.swift in Sources */, + 6397208D2CAC95040045A4DB /* LaunchAppControlWidgetView.swift in Sources */, 9FAB93742A53117C005B92B2 /* CompleteAccountView.swift in Sources */, 6304CF6A2B4C2AE800055285 /* SettingsAutoplayView.swift in Sources */, 4158388326EBD76A00F4A12B /* LibraryListCoordinator.swift in Sources */, diff --git a/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/Contents.json b/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/Contents.json new file mode 100644 index 000000000..35488c0fc --- /dev/null +++ b/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/Contents.json @@ -0,0 +1,12 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "filename" : "bookplayer.icon.svg", + "idiom" : "universal" + } + ] +} diff --git a/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/bookplayer.icon.svg b/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/bookplayer.icon.svg new file mode 100644 index 000000000..6ec43527a --- /dev/null +++ b/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/bookplayer.icon.svg @@ -0,0 +1,94 @@ + + + + + +Weight/Scale Variations +Ultralight +Thin +Light +Regular +Medium +Semibold +Bold +Heavy +Black + + + + + + + + + + +Design Variations +Symbols are supported in up to nine weights and three scales. +For optimal layout with text and other symbols, vertically align +symbols with the adjacent text. + + + + + +Margins +Leading and trailing margins on the left and right side of each symbol +can be adjusted by modifying the x-location of the margin guidelines. +Modifications are automatically applied proportionally to all +scales and weights. + + + +Exporting +Symbols should be outlined when exporting to ensure the +design is preserved when submitting to Xcode. +Template v.6.0 +Requires Xcode 16 or greater +Generated from square.and.arrow.up.circle +Typeset at 100.0 points +Small +Medium +Large + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BookPlayerWidgets/BookPlayerWidgets.swift b/BookPlayerWidgets/BookPlayerWidgets.swift index 64dd83d27..9b11fe90b 100644 --- a/BookPlayerWidgets/BookPlayerWidgets.swift +++ b/BookPlayerWidgets/BookPlayerWidgets.swift @@ -6,45 +6,51 @@ // Copyright © 2020 Tortuga Power. All rights reserved. // +import SwiftUI +import WidgetKit + #if os(watchOS) -import BookPlayerWatchKit + import BookPlayerWatchKit #else -import BookPlayerKit + import BookPlayerKit #endif -import SwiftUI -import WidgetKit #if os(iOS) -struct BookPlayerWidgetUI_Previews: PreviewProvider { - static var previews: some View { - Group { - LastPlayedWidgetView(entry: .init( - date: Date(), - items: [ - .init(relativePath: "path1", title: "Test Book Title") - ], - currentlyPlaying: nil - )) - .previewContext(WidgetPreviewContext(family: .systemSmall)) + struct BookPlayerWidgetUI_Previews: PreviewProvider { + static var previews: some View { + Group { + LastPlayedWidgetView( + entry: .init( + date: Date(), + items: [ + .init(relativePath: "path1", title: "Test Book Title") + ], + currentlyPlaying: nil + ) + ) + .previewContext(WidgetPreviewContext(family: .systemSmall)) + } } } -} #endif @main struct BookPlayerBundle: WidgetBundle { @WidgetBundleBuilder var body: some Widget { -#if os(iOS) - LastPlayedWidget() - TimeListenedWidget() - if #available(iOSApplicationExtension 16.1, *) { + #if os(iOS) + LastPlayedWidget() + TimeListenedWidget() + if #available(iOSApplicationExtension 16.1, *) { + SharedWidget() + SharedIconWidget() + } + if #available(iOSApplicationExtension 18.0, *) { + LaunchAppButton() + } + #elseif os(watchOS) SharedWidget() SharedIconWidget() - } -#elseif os(watchOS) - SharedWidget() - SharedIconWidget() -#endif + #endif } } diff --git a/BookPlayerWidgets/Phone/LaunchAppControlWidgetView.swift b/BookPlayerWidgets/Phone/LaunchAppControlWidgetView.swift new file mode 100644 index 000000000..8b1a66e6f --- /dev/null +++ b/BookPlayerWidgets/Phone/LaunchAppControlWidgetView.swift @@ -0,0 +1,43 @@ +// +// LaunchAppControlWidgetView.swift +// BookPlayerWidgetsPhone +// +// Created by Gianni Carlo on 1/10/24. +// Copyright © 2024 Tortuga Power. All rights reserved. +// + +import AppIntents +import Foundation +import SwiftUI +import WidgetKit + +@available(iOSApplicationExtension 18.0, iOS 18.0, *) +struct LaunchAppButton: ControlWidget { + var body: some ControlWidgetConfiguration { + StaticControlConfiguration( + kind: "com.bookplayer.controlcenter.launchapp" + ) { + ControlWidgetButton(action: LaunchAppIntent()) { + Label("BookPlayer", image: "bookplayer.icon") + } + } + .displayName("BookPlayer") + } +} + +@available(iOSApplicationExtension 16, iOS 16.0, *) +struct LaunchAppIntent: OpenIntent { + static var title: LocalizedStringResource = "Launch App" + @Parameter(title: "Target") + var target: LaunchAppEnum +} + +@available(iOSApplicationExtension 16.0, iOS 16.0, *) +enum LaunchAppEnum: String, AppEnum { + case home + + static var typeDisplayRepresentation = TypeDisplayRepresentation("BookPlayer Home") + static var caseDisplayRepresentations = [ + LaunchAppEnum.home: DisplayRepresentation("Home") + ] +} From 805ddd9cbbdba8b032f823870ba5c766600beb80 Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Wed, 2 Oct 2024 14:18:53 -0500 Subject: [PATCH 10/18] Update ci.yml --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b1fe92ae5..6260a5921 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,11 +9,11 @@ on: jobs: build: # https://github.com/actions/runner-images/tree/main/images/macos - runs-on: macos-14 + runs-on: macos-15 steps: - uses: actions/checkout@v4 - # We only use Xcode 15.4 + # We only use Xcode 16.0 - name: Remove unused applications run: | df -hI /dev/disk3s1s1 @@ -26,8 +26,8 @@ jobs: - name: Create Debug.xcconfig run: cp ./BuildConfiguration/Debug.template.xcconfig ./BuildConfiguration/Debug.xcconfig - name: Set Xcode version - run: sudo xcode-select -s "/Applications/Xcode_15.4.app/Contents/Developer" + run: sudo xcode-select -s "/Applications/Xcode_16.app/Contents/Developer" - name: Resolve dependencies run: xcodebuild -resolvePackageDependencies - name: Build and Run tests - run: xcodebuild -scheme BookPlayer test -testPlan Unit\ Tests -destination 'platform=iOS Simulator,name=iPhone 15,OS=17.5' + run: xcodebuild -scheme BookPlayer test -testPlan Unit\ Tests -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.0' From c6012cc71fdfed15a3383205fa0183a5d4932132 Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Fri, 4 Oct 2024 17:11:46 -0500 Subject: [PATCH 11/18] Rework how core services are created --- BookPlayer.xcodeproj/project.pbxproj | 24 +- BookPlayer/AppDelegate.swift | 256 +++++------------- .../AppIntents/CustomRewindIntent.swift | 36 +-- .../AppIntents/CustomSkipForwardIntent.swift | 36 +-- .../LastBookStartPlaybackIntent.swift | 34 +-- .../AppIntents/PausePlaybackIntent.swift | 23 +- .../DataInitializerCoordinator.swift | 75 ++--- .../Coordinators/ItemListCoordinator.swift | 37 ++- .../Coordinators/LibraryListCoordinator.swift | 98 ++++--- .../Coordinators/LoadingCoordinator.swift | 4 +- BookPlayer/Coordinators/MainCoordinator.swift | 42 ++- BookPlayer/Loading/LoadingViewModel.swift | 4 +- BookPlayer/Player/BPPlayerError.swift | 13 + BookPlayer/Player/PlayerLoaderService.swift | 76 ++++++ BookPlayer/Player/PlayerManager.swift | 34 --- BookPlayer/Player/PlayerManagerProtocol.swift | 46 ++++ BookPlayer/Services/ActionParserService.swift | 18 +- BookPlayer/Services/CarPlayManager.swift | 160 ++++++----- .../Services/ListSyncRefreshService.swift | 54 +++- .../PlayerSettingsViewController.swift | 29 +- BookPlayer/Utils/CoreServices.swift | 11 +- .../Phone/BookPlaybackToggleIntent.swift | 25 +- .../Phone/BookStartPlaybackIntent.swift | 45 --- Shared/Constants.swift | 3 - .../Extensions/UserDefaults+BookPlayer.swift | 8 - Shared/Services/LibraryService.swift | 2 +- 26 files changed, 613 insertions(+), 580 deletions(-) create mode 100644 BookPlayer/Player/BPPlayerError.swift create mode 100644 BookPlayer/Player/PlayerLoaderService.swift create mode 100644 BookPlayer/Player/PlayerManagerProtocol.swift delete mode 100644 BookPlayerWidgets/Phone/BookStartPlaybackIntent.swift diff --git a/BookPlayer.xcodeproj/project.pbxproj b/BookPlayer.xcodeproj/project.pbxproj index e858a1380..9e80bf0d3 100644 --- a/BookPlayer.xcodeproj/project.pbxproj +++ b/BookPlayer.xcodeproj/project.pbxproj @@ -358,7 +358,6 @@ 634BA5A52C176B5A0015314D /* StoryActionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 634BA5A42C176B5A0015314D /* StoryActionView.swift */; }; 634BA5A72C1777BB0015314D /* PricingBoxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 634BA5A62C1777BA0015314D /* PricingBoxView.swift */; }; 634BA5AD2C180F5E0015314D /* StoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 634BA5AC2C180F5E0015314D /* StoryViewModel.swift */; }; - 634E67462AFC7DEF00595BAC /* BookStartPlaybackIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 634E67432AFB2DF500595BAC /* BookStartPlaybackIntent.swift */; }; 6354CD9C2B4902CE006D9551 /* DebugInformationActivityItemSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6354CD9B2B4902CE006D9551 /* DebugInformationActivityItemSource.swift */; }; 6356D48C2C584EFD00994B71 /* CustomSkipForwardIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6356D48B2C584EFD00994B71 /* CustomSkipForwardIntent.swift */; }; 6356F9B52AC7CC5600B7A027 /* CancelSleepTimerIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6356F9B42AC7CC5600B7A027 /* CancelSleepTimerIntent.swift */; }; @@ -417,7 +416,6 @@ 63B760F72C32734000AA98C7 /* SecondOnboardingResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B760F62C32734000AA98C7 /* SecondOnboardingResponse.swift */; }; 63B760F92C32738E00AA98C7 /* StoryAccountSubscriptionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B760F82C32738E00AA98C7 /* StoryAccountSubscriptionService.swift */; }; 63B760FC2C33B77F00AA98C7 /* SupportProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63B760FB2C33B77F00AA98C7 /* SupportProfileView.swift */; }; - 63C1A8AF2B09158600C4B418 /* BookStartPlaybackIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 634E67432AFB2DF500595BAC /* BookStartPlaybackIntent.swift */; }; 63C1A8B02B0915EE00C4B418 /* WidgetUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 418445C2258AE11E0072DD13 /* WidgetUtils.swift */; }; 63C1A8B22B09166F00C4B418 /* WidgetEntries.swift in Sources */ = {isa = PBXBuildFile; fileRef = 637DAB092AEB3E0D006DC2D1 /* WidgetEntries.swift */; }; 63C6C2E62B5029BC00FFE0D8 /* SettingsAutolockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C6C2E52B5029BC00FFE0D8 /* SettingsAutolockView.swift */; }; @@ -428,6 +426,12 @@ 63C6C3122B54F16800FFE0D8 /* LibraryItemSyncOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C6C30F2B54F14800FFE0D8 /* LibraryItemSyncOperation.swift */; }; 63C6C3192B5E102200FFE0D8 /* SyncTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C6C3172B5E0FE700FFE0D8 /* SyncTask.swift */; }; 63C6C31A2B5E102200FFE0D8 /* SyncTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C6C3172B5E0FE700FFE0D8 /* SyncTask.swift */; }; + 63E893922CAFA89000946CD4 /* BPPlayerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893912CAFA89000946CD4 /* BPPlayerError.swift */; }; + 63E893932CAFA89000946CD4 /* BPPlayerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893912CAFA89000946CD4 /* BPPlayerError.swift */; }; + 63E893952CAFAB8F00946CD4 /* PlayerLoaderService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893942CAFAB8F00946CD4 /* PlayerLoaderService.swift */; }; + 63E893962CAFAB8F00946CD4 /* PlayerLoaderService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893942CAFAB8F00946CD4 /* PlayerLoaderService.swift */; }; + 63E893982CAFAC7500946CD4 /* PlayerManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893972CAFAC7500946CD4 /* PlayerManagerProtocol.swift */; }; + 63E893992CAFAC7500946CD4 /* PlayerManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893972CAFAC7500946CD4 /* PlayerManagerProtocol.swift */; }; 63F1C7892BB91260006B164C /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 63F1C7882BB91259006B164C /* PrivacyInfo.xcprivacy */; }; 63F1C78B2BB91E21006B164C /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 63F1C78A2BB91E1B006B164C /* PrivacyInfo.xcprivacy */; }; 63F828572AED56FA00B5CE0C /* CornerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63F828562AED56FA00B5CE0C /* CornerView.swift */; }; @@ -1121,7 +1125,6 @@ 634BA5A42C176B5A0015314D /* StoryActionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryActionView.swift; sourceTree = ""; }; 634BA5A62C1777BA0015314D /* PricingBoxView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PricingBoxView.swift; sourceTree = ""; }; 634BA5AC2C180F5E0015314D /* StoryViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryViewModel.swift; sourceTree = ""; }; - 634E67432AFB2DF500595BAC /* BookStartPlaybackIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookStartPlaybackIntent.swift; sourceTree = ""; }; 6354CD9B2B4902CE006D9551 /* DebugInformationActivityItemSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugInformationActivityItemSource.swift; sourceTree = ""; }; 6356D48B2C584EFD00994B71 /* CustomSkipForwardIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomSkipForwardIntent.swift; sourceTree = ""; }; 6356F9B42AC7CC5600B7A027 /* CancelSleepTimerIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancelSleepTimerIntent.swift; sourceTree = ""; }; @@ -1192,6 +1195,9 @@ 63C6C30B2B538B7A00FFE0D8 /* SyncTasksStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTasksStorage.swift; sourceTree = ""; }; 63C6C30F2B54F14800FFE0D8 /* LibraryItemSyncOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryItemSyncOperation.swift; sourceTree = ""; }; 63C6C3172B5E0FE700FFE0D8 /* SyncTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTask.swift; sourceTree = ""; }; + 63E893912CAFA89000946CD4 /* BPPlayerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPPlayerError.swift; sourceTree = ""; }; + 63E893942CAFAB8F00946CD4 /* PlayerLoaderService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerLoaderService.swift; sourceTree = ""; }; + 63E893972CAFAC7500946CD4 /* PlayerManagerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerManagerProtocol.swift; sourceTree = ""; }; 63F1C7882BB91259006B164C /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 63F1C78A2BB91E1B006B164C /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 63F828562AED56FA00B5CE0C /* CornerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerView.swift; sourceTree = ""; }; @@ -2303,7 +2309,6 @@ 63E5D6A92AECB8AB00A67B32 /* Phone */ = { isa = PBXGroup; children = ( - 634E67432AFB2DF500595BAC /* BookStartPlaybackIntent.swift */, 6309F1252B0CF1C1002B86A4 /* BookPlaybackToggleIntent.swift */, 6397208B2CAC95040045A4DB /* LaunchAppControlWidgetView.swift */, 4106413E258725F1008EB8D0 /* TimeListened */, @@ -2752,6 +2757,9 @@ 9F64C6222793C37C00B2493C /* Controls Screen */, 9F3D0CE328C2BF2A00E9E8A3 /* ButtonFree Screen */, 410D0FF01EDF659900A52EB9 /* PlayerManager.swift */, + 63E893972CAFAC7500946CD4 /* PlayerManagerProtocol.swift */, + 63E893912CAFA89000946CD4 /* BPPlayerError.swift */, + 63E893942CAFAB8F00946CD4 /* PlayerLoaderService.swift */, 6308260C2AF6C312002ACE0D /* WidgetReloadService.swift */, 9F5011F82A6580800075FEBA /* ShakeMotionService.swift */, C3EC372D206EE0650094B4E8 /* SleepTimer.swift */, @@ -3463,6 +3471,7 @@ 6397208A2CAC5C870045A4DB /* LastPlayedModel.swift in Sources */, 417D9994256DE3FB00C3B753 /* LastPlayedWidgetView.swift in Sources */, 41A359C7276232E00020D5F5 /* MappingModel_v7_to_v8.xcmappingmodel in Sources */, + 63E893992CAFAC7500946CD4 /* PlayerManagerProtocol.swift in Sources */, 416A29AA2569658100605395 /* BookPlayerWidgets.swift in Sources */, 630826052AF522FF002ACE0D /* RectangularView.swift in Sources */, 41D20DB425D5F5A100AAEE30 /* MappingModel_v1_to_v2.xcmappingmodel in Sources */, @@ -3471,16 +3480,17 @@ 630826032AF5225F002ACE0D /* CircularView.swift in Sources */, 6397208C2CAC95040045A4DB /* LaunchAppControlWidgetView.swift in Sources */, 630826042AF522EA002ACE0D /* SharedWidgetEntry.swift in Sources */, + 63E893962CAFAB8F00946CD4 /* PlayerLoaderService.swift in Sources */, 41064152258726D2008EB8D0 /* TimeListenedMediumView.swift in Sources */, 41C3396A25E04112003ED2B0 /* MappingModel_v2_to_v3.xcmappingmodel in Sources */, 416A29DA256AB6A900605395 /* BookPlayer.xcdatamodeld in Sources */, 630826112AF6CA44002ACE0D /* SharedIconWidget.swift in Sources */, 637DAB0B2AEB3F6D006DC2D1 /* WidgetEntries.swift in Sources */, 418CABB625EF28FC00D8C878 /* MappingModel_v3_to_v4.xcmappingmodel in Sources */, + 63E893932CAFA89000946CD4 /* BPPlayerError.swift in Sources */, 41ADD6DA2570AC6300660C64 /* RecentBooksWidgetView.swift in Sources */, 630826162AF6CABD002ACE0D /* SharedIconWidgetEntry.swift in Sources */, 9FF383D52A40F97000BBAC11 /* MappingModel_v8_to_v9.xcmappingmodel in Sources */, - 634E67462AFC7DEF00595BAC /* BookStartPlaybackIntent.swift in Sources */, 639720832CAB0C380045A4DB /* LastPlayedView.swift in Sources */, 639720852CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */, 630826072AF52831002ACE0D /* SharedWidget.swift in Sources */, @@ -3501,6 +3511,7 @@ 9F4691F02800C97000A8F0E8 /* CompleteAccountViewModel.swift in Sources */, 9F2681AD2888B26100359BD3 /* LoginBenefitView.swift in Sources */, 634BA5A72C1777BB0015314D /* PricingBoxView.swift in Sources */, + 63E893982CAFAC7500946CD4 /* PlayerManagerProtocol.swift in Sources */, 9F588DBF2902C798000DA799 /* ComposedButton.swift in Sources */, 4151A6B326E491A800E49DBE /* NibLoadableView.swift in Sources */, 4197FAFC267E480100811CC8 /* ImportViewController.swift in Sources */, @@ -3584,6 +3595,7 @@ 634BA5A12C174F9D0015314D /* StoryViewerViewModel.swift in Sources */, 4142964921F2E2BA004356DA /* ThemeCellView.swift in Sources */, 9F4691F72800F85600A8F0E8 /* AccountViewModel.swift in Sources */, + 63E893922CAFA89000946CD4 /* BPPlayerError.swift in Sources */, 4160A0A123F304530039166B /* LocalizableLabel.swift in Sources */, 4137BBCC272DAF2E009ED9FE /* MVVMControllerProtocol.swift in Sources */, C318D3AD208CF624000666F8 /* PlayerJumpIcon.swift in Sources */, @@ -3601,6 +3613,7 @@ 4138CE1C26E5B42F0014F11E /* BookmarksViewModel.swift in Sources */, 9F3D0CE528C2BF5C00E9E8A3 /* ButtonFreeViewController.swift in Sources */, 4197240021874D5F00AB1190 /* UserActivityManager.swift in Sources */, + 63E893952CAFAB8F00946CD4 /* PlayerLoaderService.swift in Sources */, 634BA5972C161FBE0015314D /* StoryView.swift in Sources */, 6356F9C52AC86D9200B7A027 /* BPAppShortcuts.swift in Sources */, 69343D332133844D000C425E /* VoiceOverService.swift in Sources */, @@ -3630,7 +3643,6 @@ 415B274421FAE47200F9D9B7 /* LoadingView.swift in Sources */, 41E79BED26C61D2B00EA9FFF /* PlayPauseIconView.swift in Sources */, 9F4691F52800F84800A8F0E8 /* AccountViewController.swift in Sources */, - 63C1A8AF2B09158600C4B418 /* BookStartPlaybackIntent.swift in Sources */, 9FEC87B027FA9F0F006C71D5 /* LoginViewController.swift in Sources */, 9F00A5FA294F8BFE005EA316 /* ClearableTextField.swift in Sources */, 9F5FBB08293EDCD8009F4B0E /* ItemDetailsViewController.swift in Sources */, diff --git a/BookPlayer/AppDelegate.swift b/BookPlayer/AppDelegate.swift index bddec417a..b28bcb4ba 100644 --- a/BookPlayer/AppDelegate.swift +++ b/BookPlayer/AppDelegate.swift @@ -7,6 +7,7 @@ // import AVFoundation +import AppIntents import BackgroundTasks import BookPlayerKit import Combine @@ -30,13 +31,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { var documentFolderWatcher: DirectoryWatcher? var sharedFolderWatcher: DirectoryWatcher? - var dataManager: DataManager? - var accountService: AccountServiceProtocol? - var syncService: SyncServiceProtocol? - var libraryService: LibraryService? - var playbackService: PlaybackServiceProtocol? - var playerManager: PlayerManagerProtocol? - var watchConnectivityService: PhoneWatchConnectivityService? + let databaseInitializer = DatabaseInitializer() + var coreServices: CoreServices? + /// Internal property used as a fallback in ``activeSceneDelegate`` var lastSceneToResignActive: SceneDelegate? /// Access the current (or last) active scene delegate to present VCs or alerts @@ -53,11 +50,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } /// Reference for observers private var crashReportsAccessObserver: NSKeyValueObservation? - private var sharedWidgetActionURLObserver: NSKeyValueObservation? /// Background refresh task identifier private lazy var refreshTaskIdentifier = "\(Bundle.main.configurationString(for: .bundleIdentifier)).background.refresh" + /// Reference to the task that creates the core services + var setupCoreServicesTask: Task<(), Error>? + var errorCoreServicesSetup: Error? + func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? @@ -83,8 +83,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { self.setupSentry() // Setup Realm self.setupRealm() - // Setup observer for interactive widgets - self.setupSharedWidgetActionObserver() + // Setup core services + self.setupCoreServices() return true } @@ -104,62 +104,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { completionHandler(response) } - // swiftlint:disable:next function_body_length func createCoreServicesIfNeeded(from stack: CoreDataStack) -> CoreServices { - let dataManager: DataManager - - if let sharedDataManager = AppDelegate.shared?.dataManager { - dataManager = sharedDataManager - } else { - dataManager = DataManager(coreDataStack: stack) - AppDelegate.shared?.dataManager = dataManager - } - - let accountService: AccountServiceProtocol - - if let sharedAccountService = AppDelegate.shared?.accountService { - accountService = sharedAccountService + if let coreServices = self.coreServices { + return coreServices } else { - accountService = AccountService(dataManager: dataManager) - AppDelegate.shared?.accountService = accountService - } - - let libraryService: LibraryService - - if let sharedLibraryService = AppDelegate.shared?.libraryService { - libraryService = sharedLibraryService - } else { - libraryService = LibraryService(dataManager: dataManager) - AppDelegate.shared?.libraryService = libraryService - } - - let syncService: SyncServiceProtocol - - if let sharedSyncService = AppDelegate.shared?.syncService { - syncService = sharedSyncService - } else { - syncService = SyncService( + let dataManager = DataManager(coreDataStack: stack) + let accountService = AccountService(dataManager: dataManager) + let libraryService = LibraryService(dataManager: dataManager) + let syncService = SyncService( isActive: accountService.hasSyncEnabled(), libraryService: libraryService ) - AppDelegate.shared?.syncService = syncService - } - - let playbackService: PlaybackServiceProtocol - - if let sharedPlaybackService = AppDelegate.shared?.playbackService { - playbackService = sharedPlaybackService - } else { - playbackService = PlaybackService(libraryService: libraryService) - AppDelegate.shared?.playbackService = playbackService - } - - let playerManager: PlayerManagerProtocol - - if let sharedPlayerManager = AppDelegate.shared?.playerManager { - playerManager = sharedPlayerManager - } else { - playerManager = PlayerManager( + let playbackService = PlaybackService(libraryService: libraryService) + let playerManager = PlayerManager( libraryService: libraryService, playbackService: playbackService, syncService: syncService, @@ -167,101 +124,31 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { shakeMotionService: ShakeMotionService(), widgetReloadService: WidgetReloadService() ) - AppDelegate.shared?.playerManager = playerManager - } - - let watchService: PhoneWatchConnectivityService - - if let sharedWatchService = AppDelegate.shared?.watchConnectivityService { - watchService = sharedWatchService - } else { - watchService = PhoneWatchConnectivityService( + let watchService = PhoneWatchConnectivityService( libraryService: libraryService, playbackService: playbackService, playerManager: playerManager ) - AppDelegate.shared?.watchConnectivityService = watchService - } - - return CoreServices( - dataManager: dataManager, - accountService: accountService, - syncService: syncService, - libraryService: libraryService, - playbackService: playbackService, - playerManager: playerManager, - watchService: watchService - ) - } - - func loadPlayer( - _ relativePath: String, - autoplay: Bool, - showPlayer: (() -> Void)?, - alertPresenter: AlertPresenter, - recordAsLastBook: Bool = true - ) { - Task { @MainActor in - let fileURL = DataManager.getProcessedFolderURL().appendingPathComponent(relativePath) - - if syncService?.isActive == false, - !FileManager.default.fileExists(atPath: fileURL.path) - { - alertPresenter.showAlert( - "file_missing_title".localized, - message: - "\("file_missing_description".localized)\n\(fileURL.lastPathComponent)", - completion: nil - ) - return - } - - // Only load if loaded book is a different one - if playerManager?.hasLoadedBook() == true, - relativePath == playerManager?.currentItem?.relativePath - { - if autoplay { - playerManager?.play() - } - showPlayer?() - return - } - - guard let libraryItem = self.libraryService?.getSimpleItem(with: relativePath) else { return } - - var item: PlayableItem? - - do { - /// If the selected item is a bound book, check that the contents are loaded - if syncService?.isActive == true, - libraryItem.type == .bound, - let contents = libraryService?.getMaxItemsCount(at: relativePath), - contents == 0 - { - _ = try await syncService?.syncListContents(at: relativePath) - } - - item = try self.playbackService?.getPlayableItem(from: libraryItem) - } catch { - alertPresenter.showAlert( - "error_title".localized, - message: error.localizedDescription, - completion: nil - ) - return - } - - guard let item = item else { return } - - playerManager?.load(item, autoplay: autoplay) + let playerLoaderService = PlayerLoaderService( + syncService: syncService, + libraryService: libraryService, + playbackService: playbackService, + playerManager: playerManager + ) + let coreServices = CoreServices( + dataManager: dataManager, + accountService: accountService, + syncService: syncService, + libraryService: libraryService, + playbackService: playbackService, + playerManager: playerManager, + playerLoaderService: playerLoaderService, + watchService: watchService + ) - if recordAsLastBook { - await MainActor.run { - libraryService?.setLibraryLastBook(with: item.relativePath) - } - } + self.coreServices = coreServices - showPlayer?() + return coreServices } } @@ -280,7 +167,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { override func accessibilityPerformMagicTap() -> Bool { guard - let playerManager = self.playerManager, + let playerManager = self.coreServices?.playerManager, playerManager.currentItem != nil else { UIAccessibility.post( @@ -306,7 +193,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { // Play / Pause center.togglePlayPauseCommand.isEnabled = true center.togglePlayPauseCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { + guard let playerManager = self?.coreServices?.playerManager else { return .commandFailed } @@ -323,7 +210,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { center.playCommand.isEnabled = true center.playCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { + guard let playerManager = self?.coreServices?.playerManager else { return .commandFailed } @@ -333,7 +220,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { center.pauseCommand.isEnabled = true center.pauseCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { + guard let playerManager = self?.coreServices?.playerManager else { return .commandFailed } @@ -349,7 +236,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { center.changePlaybackPositionCommand.isEnabled = true center.changePlaybackPositionCommand.addTarget { [weak self] remoteEvent in guard - let playerManager = self?.playerManager, + let playerManager = self?.coreServices?.playerManager, let currentItem = playerManager.currentItem, let event = remoteEvent as? MPChangePlaybackPositionCommandEvent else { return .commandFailed } @@ -374,14 +261,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { // Forward center.skipForwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.forwardInterval)] center.skipForwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { return .commandFailed } + guard let playerManager = self?.coreServices?.playerManager else { return .commandFailed } playerManager.forward() return .success } center.nextTrackCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { return .commandFailed } + guard let playerManager = self?.coreServices?.playerManager else { return .commandFailed } playerManager.forward() return .success @@ -394,7 +281,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { return .success } - guard let playerManager = self?.playerManager else { return .success } + guard let playerManager = self?.coreServices?.playerManager else { return .success } // End seeking playerManager.forward() @@ -404,14 +291,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { // Rewind center.skipBackwardCommand.preferredIntervals = [NSNumber(value: PlayerManager.rewindInterval)] center.skipBackwardCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { return .commandFailed } + guard let playerManager = self?.coreServices?.playerManager else { return .commandFailed } playerManager.rewind() return .success } center.previousTrackCommand.addTarget { [weak self] (_) -> MPRemoteCommandHandlerStatus in - guard let playerManager = self?.playerManager else { return .commandFailed } + guard let playerManager = self?.coreServices?.playerManager else { return .commandFailed } playerManager.rewind() return .success @@ -425,7 +312,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { return .success } - guard let playerManager = self?.playerManager else { return .success } + guard let playerManager = self?.coreServices?.playerManager else { return .success } // End seeking playerManager.rewind() @@ -468,30 +355,29 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { } } - func setupSharedWidgetActionObserver() { - let sharedDefaults = UserDefaults.sharedDefaults - - if let actionURL = sharedDefaults.sharedWidgetActionURL { - ActionParserService.process(actionURL) - sharedDefaults.removeObject( - forKey: Constants.UserDefaults.sharedWidgetActionURL - ) - } - - sharedWidgetActionURLObserver = sharedDefaults.observe( - \.sharedWidgetActionURL - ) { defaults, _ in - DispatchQueue.main.async { - guard let actionURL = defaults.sharedWidgetActionURL else { return } - - ActionParserService.process(actionURL) - sharedDefaults.removeObject( - forKey: Constants.UserDefaults.sharedWidgetActionURL - ) + func setupCoreServices() { + setupCoreServicesTask = Task { + do { + let stack = try await databaseInitializer.loadCoreDataStack() + let coreServices = createCoreServicesIfNeeded(from: stack) + if #available(iOS 16.0, *) { + AppDependencyManager.shared.add(dependency: coreServices.playerLoaderService) + AppDependencyManager.shared.add(dependency: coreServices.libraryService) + } + } catch { + errorCoreServicesSetup = error } } } + func resetCoreServices() { + setupCoreServicesTask?.cancel() + setupCoreServicesTask = nil + errorCoreServicesSetup = nil + databaseInitializer.cleanupStoreFiles() + setupCoreServices() + } + /// Setup or stop Sentry based on flag /// - Parameter isDisabled: Determines user preference for crash reports private func handleSentryPreference(isDisabled: Bool) { @@ -546,7 +432,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { func playLastBook() { guard - let playerManager, + let playerManager = coreServices?.playerManager, playerManager.hasLoadedBook() else { UserDefaults.standard.set(true, forKey: Constants.UserActivityPlayback) @@ -558,7 +444,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { func showPlayer() { guard - let playerManager, + let playerManager = coreServices?.playerManager, playerManager.hasLoadedBook() else { UserDefaults.standard.set(true, forKey: Constants.UserDefaults.showPlayer) @@ -583,7 +469,7 @@ extension AppDelegate { object: nil, queue: nil ) { _ in - if self.playerManager?.isPlaying != true { + if self.coreServices?.playerManager.isPlaying != true { self.scheduleAppRefresh() } } @@ -606,7 +492,7 @@ extension AppDelegate { } func handleAppRefresh(task: BGAppRefreshTask) { - guard let syncService else { return } + guard let syncService = coreServices?.syncService else { return } let refreshOperation = RefreshTaskOperation(syncService: syncService) diff --git a/BookPlayer/AppIntents/CustomRewindIntent.swift b/BookPlayer/AppIntents/CustomRewindIntent.swift index 50fdd9367..8f2bd650b 100644 --- a/BookPlayer/AppIntents/CustomRewindIntent.swift +++ b/BookPlayer/AppIntents/CustomRewindIntent.swift @@ -6,12 +6,12 @@ // Copyright © 2024 Tortuga Power. All rights reserved. // +import AppIntents import BookPlayerKit import Foundation -import AppIntents -@available(iOS 16.4, macOS 14.0, watchOS 10.0, tvOS 16.0, *) -struct CustomRewindIntent: AudioStartingIntent, ForegroundContinuableIntent { +@available(iOS 16.0, macOS 14.0, watchOS 10.0, tvOS 16.0, *) +struct CustomRewindIntent: AudioStartingIntent { static var title: LocalizedStringResource = "intent_custom_skiprewind_title" @Parameter( @@ -24,30 +24,22 @@ struct CustomRewindIntent: AudioStartingIntent, ForegroundContinuableIntent { Summary("Rewind \(\.$interval)") } - func perform() async throws -> some IntentResult { - let seconds = interval.converted(to: .seconds).value - let stack = try await DatabaseInitializer().loadCoreDataStack() - - let continuation: (@MainActor () async throws -> Void) = { - let actionString = CommandParser.createActionString( - from: .skipRewind, - parameters: [URLQueryItem(name: "interval", value: "\(seconds)")] - ) - let actionURL = URL(string: actionString)! - UIApplication.shared.open(actionURL) - } + @Dependency + var playerLoaderService: PlayerLoaderService - guard let appDelegate = await AppDelegate.shared else { - throw needsToContinueInForegroundError(continuation: continuation) - } + @Dependency + var libraryService: LibraryService - let coreServices = await appDelegate.createCoreServicesIfNeeded(from: stack) + func perform() async throws -> some IntentResult { + let seconds = interval.converted(to: .seconds).value - guard coreServices.playerManager.hasLoadedBook() else { - throw needsToContinueInForegroundError(continuation: continuation) + if !playerLoaderService.playerManager.hasLoadedBook(), + let book = libraryService.getLastPlayedItems(limit: 1)?.first + { + try await playerLoaderService.loadPlayer(book.relativePath, autoplay: false) } - coreServices.playerManager.skip(-seconds) + playerLoaderService.playerManager.skip(-seconds) return .result() } diff --git a/BookPlayer/AppIntents/CustomSkipForwardIntent.swift b/BookPlayer/AppIntents/CustomSkipForwardIntent.swift index f354c887e..092d8d13f 100644 --- a/BookPlayer/AppIntents/CustomSkipForwardIntent.swift +++ b/BookPlayer/AppIntents/CustomSkipForwardIntent.swift @@ -6,12 +6,12 @@ // Copyright © 2024 Tortuga Power. All rights reserved. // +import AppIntents import BookPlayerKit import Foundation -import AppIntents -@available(iOS 16.4, macOS 14.0, watchOS 10.0, tvOS 16.0, *) -struct CustomSkipForwardIntent: AudioStartingIntent, ForegroundContinuableIntent { +@available(iOS 16.0, macOS 14.0, watchOS 10.0, tvOS 16.0, *) +struct CustomSkipForwardIntent: AudioStartingIntent { static var title: LocalizedStringResource = "intent_custom_skipforward_title" @Parameter( @@ -24,30 +24,22 @@ struct CustomSkipForwardIntent: AudioStartingIntent, ForegroundContinuableIntent Summary("Skip forward \(\.$interval)") } - func perform() async throws -> some IntentResult { - let seconds = interval.converted(to: .seconds).value - let stack = try await DatabaseInitializer().loadCoreDataStack() - - let continuation: (@MainActor () async throws -> Void) = { - let actionString = CommandParser.createActionString( - from: .skipForward, - parameters: [URLQueryItem(name: "interval", value: "\(seconds)")] - ) - let actionURL = URL(string: actionString)! - UIApplication.shared.open(actionURL) - } + @Dependency + var playerLoaderService: PlayerLoaderService - guard let appDelegate = await AppDelegate.shared else { - throw needsToContinueInForegroundError(continuation: continuation) - } + @Dependency + var libraryService: LibraryService - let coreServices = await appDelegate.createCoreServicesIfNeeded(from: stack) + func perform() async throws -> some IntentResult { + let seconds = interval.converted(to: .seconds).value - guard coreServices.playerManager.hasLoadedBook() else { - throw needsToContinueInForegroundError(continuation: continuation) + if !playerLoaderService.playerManager.hasLoadedBook(), + let book = libraryService.getLastPlayedItems(limit: 1)?.first + { + try await playerLoaderService.loadPlayer(book.relativePath, autoplay: false) } - coreServices.playerManager.skip(seconds) + playerLoaderService.playerManager.skip(seconds) return .result() } diff --git a/BookPlayer/AppIntents/LastBookStartPlaybackIntent.swift b/BookPlayer/AppIntents/LastBookStartPlaybackIntent.swift index 5abdf911c..7c3659ea7 100644 --- a/BookPlayer/AppIntents/LastBookStartPlaybackIntent.swift +++ b/BookPlayer/AppIntents/LastBookStartPlaybackIntent.swift @@ -6,40 +6,26 @@ // Copyright © 2023 Tortuga Power. All rights reserved. // -import Foundation import AppIntents import BookPlayerKit +import Foundation -@available(iOS 16.4, macOS 14.0, watchOS 10.0, *) -struct LastBookStartPlaybackIntent: AudioStartingIntent, ForegroundContinuableIntent { +@available(iOS 16.0, macOS 14.0, watchOS 10.0, *) +struct LastBookStartPlaybackIntent: AudioStartingIntent { static var title: LocalizedStringResource = "intent_lastbook_play_title" - func perform() async throws -> some IntentResult { - let stack = try await DatabaseInitializer().loadCoreDataStack() - - guard let appDelegate = await AppDelegate.shared else { - throw needsToContinueInForegroundError { - let actionString = CommandParser.createActionString( - from: .play, - parameters: [URLQueryItem(name: "autoplay", value: "true")] - ) - let actionURL = URL(string: actionString)! - UIApplication.shared.open(actionURL) - } - } + @Dependency + var playerLoaderService: PlayerLoaderService - let coreServices = await appDelegate.createCoreServicesIfNeeded(from: stack) + @Dependency + var libraryService: LibraryService - guard let book = coreServices.libraryService.getLastPlayedItems(limit: 1)?.first else { + func perform() async throws -> some IntentResult { + guard let book = libraryService.getLastPlayedItems(limit: 1)?.first else { throw "intent_lastbook_empty_error".localized } - await appDelegate.loadPlayer( - book.relativePath, - autoplay: true, - showPlayer: nil, - alertPresenter: VoidAlertPresenter() - ) + try await playerLoaderService.loadPlayer(book.relativePath, autoplay: true) return .result() } diff --git a/BookPlayer/AppIntents/PausePlaybackIntent.swift b/BookPlayer/AppIntents/PausePlaybackIntent.swift index 210a78d9b..f911ddbf8 100644 --- a/BookPlayer/AppIntents/PausePlaybackIntent.swift +++ b/BookPlayer/AppIntents/PausePlaybackIntent.swift @@ -6,28 +6,19 @@ // Copyright © 2023 Tortuga Power. All rights reserved. // -import Foundation import AppIntents import BookPlayerKit +import Foundation -@available(iOS 16.4, macOS 14.0, watchOS 10.0, *) -struct PausePlaybackIntent: AudioStartingIntent, ForegroundContinuableIntent { +@available(iOS 16.0, macOS 14.0, watchOS 10.0, *) +struct PausePlaybackIntent: AudioStartingIntent { static var title: LocalizedStringResource = "intent_playback_pause_title" - func perform() async throws -> some IntentResult { - let stack = try await DatabaseInitializer().loadCoreDataStack() - - guard let appDelegate = await AppDelegate.shared else { - throw needsToContinueInForegroundError { - let actionString = CommandParser.createActionString(from: .pause, parameters: []) - let actionURL = URL(string: actionString)! - UIApplication.shared.open(actionURL) - } - } - - let coreServices = await appDelegate.createCoreServicesIfNeeded(from: stack) + @Dependency + var playerLoaderService: PlayerLoaderService - coreServices.playerManager.pause() + func perform() async throws -> some IntentResult { + playerLoaderService.playerManager.pause() return .result() } diff --git a/BookPlayer/Coordinators/DataInitializerCoordinator.swift b/BookPlayer/Coordinators/DataInitializerCoordinator.swift index 76d4e2a96..3ea4d86d4 100644 --- a/BookPlayer/Coordinators/DataInitializerCoordinator.swift +++ b/BookPlayer/Coordinators/DataInitializerCoordinator.swift @@ -15,7 +15,7 @@ class DataInitializerCoordinator: BPLogger { let databaseInitializer: DatabaseInitializer = DatabaseInitializer() let alertPresenter: AlertPresenter - var onFinish: ((CoreDataStack) -> Void)? + var onFinish: (() -> Void)? init(alertPresenter: AlertPresenter) { self.alertPresenter = alertPresenter @@ -28,13 +28,22 @@ class DataInitializerCoordinator: BPLogger { } func initializeLibrary(isRecoveryAttempt: Bool) async { - do { - let stack = try await databaseInitializer.loadCoreDataStack() - finishLibrarySetup(stack, fromRecovery: isRecoveryAttempt) - } catch let error as NSError where error.domain == NSPOSIXErrorDomain && ( - error.code == ENOSPC - || error.code == NSFileWriteOutOfSpaceError - ) { + let appDelegate = await AppDelegate.shared! + _ = await appDelegate.setupCoreServicesTask?.result + + if let errorCoreServicesSetup = await appDelegate.errorCoreServicesSetup { + await handleError(errorCoreServicesSetup as NSError) + return + } + + await finishLibrarySetup(fromRecovery: isRecoveryAttempt) + } + + func handleError(_ error: NSError) async { + if error.domain == NSPOSIXErrorDomain + && (error.code == ENOSPC + || error.code == NSFileWriteOutOfSpaceError) + { // CoreData may fail if device doesn't have space await MainActor.run { alertPresenter.showAlert( @@ -43,19 +52,12 @@ class DataInitializerCoordinator: BPLogger { completion: nil ) } - } catch let error as NSError where ( - error.code == NSMigrationError || - error.code == NSMigrationConstraintViolationError || - error.code == NSMigrationCancelledError || - error.code == NSMigrationMissingSourceModelError || - error.code == NSMigrationMissingMappingModelError || - error.code == NSMigrationManagerSourceStoreError || - error.code == NSMigrationManagerDestinationStoreError || - error.code == NSEntityMigrationPolicyError || - error.code == NSValidationMultipleErrorsError || - error.code == NSValidationMissingMandatoryPropertyError - ) { - // TODO: We can handle `isRecoveryAttempt` to show a different error message + } else if error.code == NSMigrationError || error.code == NSMigrationConstraintViolationError + || error.code == NSMigrationCancelledError || error.code == NSMigrationMissingSourceModelError + || error.code == NSMigrationMissingMappingModelError || error.code == NSMigrationManagerSourceStoreError + || error.code == NSMigrationManagerDestinationStoreError || error.code == NSEntityMigrationPolicyError + || error.code == NSValidationMultipleErrorsError || error.code == NSValidationMissingMandatoryPropertyError + { Self.logger.warning("Failed to perform migration, attempting recovery with the loading library sequence") await MainActor.run { alertPresenter.showAlert( @@ -65,35 +67,33 @@ class DataInitializerCoordinator: BPLogger { recoverLibraryFromFailedMigration() } } - } catch { - let error = error as NSError + } else { fatalError("Unresolved error \(error), \(error.userInfo)") } } func recoverLibraryFromFailedMigration() { Task { - databaseInitializer.cleanupStoreFiles() + await AppDelegate.shared?.resetCoreServices() await initializeLibrary(isRecoveryAttempt: true) } } - func finishLibrarySetup(_ stack: CoreDataStack, fromRecovery: Bool) { - let dataManager = DataManager(coreDataStack: stack) - let libraryService = LibraryService(dataManager: dataManager) + func finishLibrarySetup(fromRecovery: Bool) async { + let coreServices = await AppDelegate.shared!.coreServices! setupDefaultState( - libraryService: libraryService, - dataManager: dataManager + libraryService: coreServices.libraryService, + dataManager: coreServices.dataManager ) if fromRecovery { let files = getLibraryFiles() - libraryService.insertItems(from: files) + coreServices.libraryService.insertItems(from: files) } - DispatchQueue.main.async { - self.onFinish?(stack) + await MainActor.run { + self.onFinish?() } } @@ -101,10 +101,12 @@ class DataInitializerCoordinator: BPLogger { let enumerator = FileManager.default.enumerator( at: DataManager.getProcessedFolderURL(), includingPropertiesForKeys: [.isDirectoryKey], - options: [.skipsHiddenFiles, .skipsSubdirectoryDescendants], errorHandler: { (url, error) -> Bool in + options: [.skipsHiddenFiles, .skipsSubdirectoryDescendants], + errorHandler: { (url, error) -> Bool in print("directoryEnumerator error at \(url): ", error) return true - })! + } + )! var files = [URL]() for case let fileURL as URL in enumerator { files.append(fileURL) @@ -124,8 +126,9 @@ class DataInitializerCoordinator: BPLogger { let storedIconId = UserDefaults.standard.string(forKey: Constants.UserDefaults.appIcon) sharedDefaults.set(storedIconId, forKey: Constants.UserDefaults.appIcon) } else if let sharedAppIcon = sharedDefaults.string(forKey: Constants.UserDefaults.appIcon), - let localAppIcon = UserDefaults.standard.string(forKey: Constants.UserDefaults.appIcon), - sharedAppIcon != localAppIcon { + let localAppIcon = UserDefaults.standard.string(forKey: Constants.UserDefaults.appIcon), + sharedAppIcon != localAppIcon + { sharedDefaults.set(localAppIcon, forKey: Constants.UserDefaults.appIcon) UserDefaults.standard.removeObject(forKey: Constants.UserDefaults.appIcon) } diff --git a/BookPlayer/Coordinators/ItemListCoordinator.swift b/BookPlayer/Coordinators/ItemListCoordinator.swift index 13e2e90ec..3bd00d6c4 100644 --- a/BookPlayer/Coordinators/ItemListCoordinator.swift +++ b/BookPlayer/Coordinators/ItemListCoordinator.swift @@ -70,6 +70,7 @@ class ItemListCoordinator: NSObject, Coordinator, AlertPresenter, BPLogger { flow.navigationController.present(nav, animated: true) } + @MainActor func showPlayer() { let playerCoordinator = PlayerCoordinator( flow: .modalOnlyFlow(presentingController: flow.navigationController, modalPresentationStyle: .overFullScreen), @@ -103,14 +104,29 @@ class ItemListCoordinator: NSObject, Coordinator, AlertPresenter, BPLogger { } func loadPlayer(_ relativePath: String) { - AppDelegate.shared?.loadPlayer( - relativePath, - autoplay: true, - showPlayer: { [weak self] in - self?.showPlayer() - }, - alertPresenter: self - ) + Task { + let alertPresenter: AlertPresenter = self + do { + try await AppDelegate.shared?.coreServices?.playerLoaderService.loadPlayer( + relativePath, + autoplay: true + ) + await self.showPlayer() + } catch BPPlayerError.fileMissing { + alertPresenter.showAlert( + "file_missing_title".localized, + message: + "\("file_missing_description".localized)\n\(relativePath)", + completion: nil + ) + } catch { + alertPresenter.showAlert( + "error_title".localized, + message: error.localizedDescription, + completion: nil + ) + } + } } func showMiniPlayer(flag: Bool) { @@ -131,7 +147,7 @@ extension ItemListCoordinator { UTType.audio, UTType.movie, UTType.zip, - UTType.folder + UTType.folder, ], asCopy: true ) @@ -151,7 +167,8 @@ extension ItemListCoordinator { shareController.excludedActivityTypes = [.copyToPasteboard] if let popoverPresentationController = shareController.popoverPresentationController, - let view = flow.navigationController.topViewController?.view { + let view = flow.navigationController.topViewController?.view + { popoverPresentationController.permittedArrowDirections = [] popoverPresentationController.sourceView = view popoverPresentationController.sourceRect = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0) diff --git a/BookPlayer/Coordinators/LibraryListCoordinator.swift b/BookPlayer/Coordinators/LibraryListCoordinator.swift index 8f22401a3..7ad00f902 100644 --- a/BookPlayer/Coordinators/LibraryListCoordinator.swift +++ b/BookPlayer/Coordinators/LibraryListCoordinator.swift @@ -57,7 +57,7 @@ class LibraryListCoordinator: ItemListCoordinator, UINavigationControllerDelegat networkClient: NetworkClient(), libraryService: self.libraryService, playbackService: self.playbackService, - syncService: self.syncService, + syncService: self.syncService, importManager: importManager, listRefreshService: listRefreshService, themeAccent: ThemeManager.shared.currentTheme.linkColor @@ -104,7 +104,7 @@ class LibraryListCoordinator: ItemListCoordinator, UINavigationControllerDelegat self.documentPickerDelegate = vc - AppDelegate.shared?.watchConnectivityService?.startSession() + AppDelegate.shared?.coreServices?.watchService.startSession() } func handleLibraryLoaded() { @@ -145,15 +145,16 @@ class LibraryListCoordinator: ItemListCoordinator, UINavigationControllerDelegat fileSubscription = importManager.observeFiles() .receive(on: DispatchQueue.main) .sink { [weak self] files in - guard let self = self, - !files.isEmpty, - self.shouldShowImportScreen() else { return } + guard let self = self, + !files.isEmpty, + self.shouldShowImportScreen() + else { return } - self.showImport() - } + self.showImport() + } importOperationSubscription = importManager.operationPublisher.sink(receiveValue: { [weak self] operation in - guard + guard let self, let lastItemListViewController = self.flow.navigationController.viewControllers.last as? ItemListViewController else { @@ -161,7 +162,10 @@ class LibraryListCoordinator: ItemListCoordinator, UINavigationControllerDelegat } lastItemListViewController.setEditing(false, animated: false) - let loadingTitle = String.localizedStringWithFormat("import_processing_description".localized, operation.files.count) + let loadingTitle = String.localizedStringWithFormat( + "import_processing_description".localized, + operation.files.count + ) lastItemListViewController.showLoadView(true, title: loadingTitle) operation.completionBlock = { @@ -189,29 +193,32 @@ class LibraryListCoordinator: ItemListCoordinator, UINavigationControllerDelegat @MainActor func notifyPendingFiles() { // Get reference of all the files located inside the Documents, Shared and Inbox folders - let documentsURLs = ((try? FileManager.default.contentsOfDirectory( - at: DataManager.getDocumentsFolderURL(), - includingPropertiesForKeys: nil, - options: .skipsSubdirectoryDescendants - )) ?? []) + let documentsURLs = + ((try? FileManager.default.contentsOfDirectory( + at: DataManager.getDocumentsFolderURL(), + includingPropertiesForKeys: nil, + options: .skipsSubdirectoryDescendants + )) ?? []) .filter { $0.lastPathComponent != DataManager.processedFolderName - && $0.lastPathComponent != DataManager.inboxFolderName - && $0.lastPathComponent != DataManager.backupFolderName - && $0.lastPathComponent != DataManager.trashFolderName + && $0.lastPathComponent != DataManager.inboxFolderName + && $0.lastPathComponent != DataManager.backupFolderName + && $0.lastPathComponent != DataManager.trashFolderName } - let sharedURLs = (try? FileManager.default.contentsOfDirectory( - at: DataManager.getSharedFilesFolderURL(), - includingPropertiesForKeys: nil, - options: .skipsSubdirectoryDescendants - )) ?? [] + let sharedURLs = + (try? FileManager.default.contentsOfDirectory( + at: DataManager.getSharedFilesFolderURL(), + includingPropertiesForKeys: nil, + options: .skipsSubdirectoryDescendants + )) ?? [] - let inboxURLs = (try? FileManager.default.contentsOfDirectory( - at: DataManager.getInboxFolderURL(), - includingPropertiesForKeys: nil, - options: .skipsSubdirectoryDescendants - )) ?? [] + let inboxURLs = + (try? FileManager.default.contentsOfDirectory( + at: DataManager.getInboxFolderURL(), + includingPropertiesForKeys: nil, + options: .skipsSubdirectoryDescendants + )) ?? [] let urls = documentsURLs + sharedURLs + inboxURLs @@ -225,23 +232,38 @@ class LibraryListCoordinator: ItemListCoordinator, UINavigationControllerDelegat let libraryItem = libraryService.getLibraryLastItem() else { return } - AppDelegate.shared?.loadPlayer( - libraryItem.relativePath, - autoplay: false, - showPlayer: { [weak self] in + Task { + let alertPresenter: AlertPresenter = self + do { + try await AppDelegate.shared?.coreServices?.playerLoaderService.loadPlayer( + libraryItem.relativePath, + autoplay: false, + recordAsLastBook: false + ) if UserDefaults.standard.bool(forKey: Constants.UserActivityPlayback) { UserDefaults.standard.removeObject(forKey: Constants.UserActivityPlayback) - self?.playerManager.play() + self.playerManager.play() } if UserDefaults.standard.bool(forKey: Constants.UserDefaults.showPlayer) { UserDefaults.standard.removeObject(forKey: Constants.UserDefaults.showPlayer) - self?.showPlayer() + self.showPlayer() } - }, - alertPresenter: self, - recordAsLastBook: false - ) + } catch BPPlayerError.fileMissing { + alertPresenter.showAlert( + "file_missing_title".localized, + message: + "\("file_missing_description".localized)\n\(libraryItem.relativePath)", + completion: nil + ) + } catch { + alertPresenter.showAlert( + "error_title".localized, + message: error.localizedDescription, + completion: nil + ) + } + } } func processFiles(urls: [URL]) { @@ -263,7 +285,7 @@ class LibraryListCoordinator: ItemListCoordinator, UINavigationControllerDelegat } func showImport() { - guard + guard let topVC = AppDelegate.shared?.activeSceneDelegate?.startingNavigationController.getTopVisibleViewController() else { return } diff --git a/BookPlayer/Coordinators/LoadingCoordinator.swift b/BookPlayer/Coordinators/LoadingCoordinator.swift index 8a21ec0ae..31841cbb5 100644 --- a/BookPlayer/Coordinators/LoadingCoordinator.swift +++ b/BookPlayer/Coordinators/LoadingCoordinator.swift @@ -25,8 +25,8 @@ class LoadingCoordinator: Coordinator, AlertPresenter { flow.startPresentation(vc, animated: false) } - func didFinishLoadingSequence(coreDataStack: CoreDataStack) { - let coreServices = AppDelegate.shared!.createCoreServicesIfNeeded(from: coreDataStack) + func didFinishLoadingSequence() { + let coreServices = AppDelegate.shared!.coreServices! let coordinator = MainCoordinator( navigationController: flow.navigationController, diff --git a/BookPlayer/Coordinators/MainCoordinator.swift b/BookPlayer/Coordinators/MainCoordinator.swift index dc16b8612..204e2c248 100644 --- a/BookPlayer/Coordinators/MainCoordinator.swift +++ b/BookPlayer/Coordinators/MainCoordinator.swift @@ -91,7 +91,7 @@ class MainCoordinator: NSObject { listRefreshService: ListSyncRefreshService( playerManager: playerManager, syncService: syncService - ), + ), accountService: self.accountService ) playerManager.syncProgressDelegate = libraryCoordinator @@ -115,7 +115,7 @@ class MainCoordinator: NSObject { func startSettingsCoordinator(with tabBarController: UITabBarController) { let settingsCoordinator = SettingsCoordinator( flow: .pushFlow(navigationController: AppNavigationController.instantiate(from: .Settings)), - libraryService: self.libraryService, + libraryService: self.libraryService, syncService: self.syncService, accountService: self.accountService ) @@ -148,16 +148,31 @@ class MainCoordinator: NSObject { } func loadPlayer(_ relativePath: String, autoplay: Bool, showPlayer: Bool) { - AppDelegate.shared?.loadPlayer( - relativePath, - autoplay: autoplay, - showPlayer: { [weak self] in + Task { + let alertPresenter: AlertPresenter = getLibraryCoordinator() ?? self + do { + try await AppDelegate.shared?.coreServices?.playerLoaderService.loadPlayer( + relativePath, + autoplay: autoplay + ) if showPlayer { - self?.showPlayer() + self.showPlayer() } - }, - alertPresenter: (getLibraryCoordinator() ?? self) - ) + } catch BPPlayerError.fileMissing { + alertPresenter.showAlert( + "file_missing_title".localized, + message: + "\("file_missing_description".localized)\n\(relativePath)", + completion: nil + ) + } catch { + alertPresenter.showAlert( + "error_title".localized, + message: error.localizedDescription, + completion: nil + ) + } + } } func showPlayer() { @@ -211,9 +226,10 @@ extension MainCoordinator: Themeable { return } // This fixes native components like alerts having the proper color theme - AppDelegate.shared?.activeSceneDelegate?.window?.overrideUserInterfaceStyle = theme.useDarkVariant - ? .dark - : .light + AppDelegate.shared?.activeSceneDelegate?.window?.overrideUserInterfaceStyle = + theme.useDarkVariant + ? .dark + : .light } } diff --git a/BookPlayer/Loading/LoadingViewModel.swift b/BookPlayer/Loading/LoadingViewModel.swift index d28f58551..be228c8ff 100644 --- a/BookPlayer/Loading/LoadingViewModel.swift +++ b/BookPlayer/Loading/LoadingViewModel.swift @@ -16,8 +16,8 @@ class LoadingViewModel: ViewModelProtocol { func initializeDataIfNeeded() { let dataInitializerCoordinator = DataInitializerCoordinator(alertPresenter: self.coordinator) - dataInitializerCoordinator.onFinish = { stack in - self.coordinator.didFinishLoadingSequence(coreDataStack: stack) + dataInitializerCoordinator.onFinish = { + self.coordinator.didFinishLoadingSequence() } dataInitializerCoordinator.start() diff --git a/BookPlayer/Player/BPPlayerError.swift b/BookPlayer/Player/BPPlayerError.swift new file mode 100644 index 000000000..56361f883 --- /dev/null +++ b/BookPlayer/Player/BPPlayerError.swift @@ -0,0 +1,13 @@ +// +// BPPlayerError.swift +// BookPlayer +// +// Created by Gianni Carlo on 3/10/24. +// Copyright © 2024 Tortuga Power. All rights reserved. +// + +import Foundation + +enum BPPlayerError: Error { + case fileMissing +} diff --git a/BookPlayer/Player/PlayerLoaderService.swift b/BookPlayer/Player/PlayerLoaderService.swift new file mode 100644 index 000000000..31ba3a0cc --- /dev/null +++ b/BookPlayer/Player/PlayerLoaderService.swift @@ -0,0 +1,76 @@ +// +// PlayerLoaderService.swift +// BookPlayer +// +// Created by Gianni Carlo on 3/10/24. +// Copyright © 2024 Tortuga Power. All rights reserved. +// + +import BookPlayerKit +import Foundation + +final class PlayerLoaderService: @unchecked Sendable { + var syncService: SyncServiceProtocol + var libraryService: LibraryServiceProtocol + var playbackService: PlaybackServiceProtocol + var playerManager: PlayerManagerProtocol + + init( + syncService: SyncServiceProtocol, + libraryService: LibraryServiceProtocol, + playbackService: PlaybackServiceProtocol, + playerManager: PlayerManagerProtocol + ) { + self.syncService = syncService + self.libraryService = libraryService + self.playbackService = playbackService + self.playerManager = playerManager + } + + @MainActor + func loadPlayer( + _ relativePath: String, + autoplay: Bool, + recordAsLastBook: Bool = true + ) async throws { + let fileURL = DataManager.getProcessedFolderURL().appendingPathComponent(relativePath) + + if syncService.isActive == false, + !FileManager.default.fileExists(atPath: fileURL.path) + { + throw BPPlayerError.fileMissing + } + + // Only load if loaded book is a different one + if playerManager.hasLoadedBook() == true, + relativePath == playerManager.currentItem?.relativePath + { + if autoplay { + playerManager.play() + } + return + } + + guard + let libraryItem = self.libraryService.getSimpleItem(with: relativePath) + else { return } + + /// If the selected item is a bound book, check that the contents are loaded + if syncService.isActive == true, + libraryItem.type == .bound, + libraryService.getMaxItemsCount(at: relativePath) == 0 + { + _ = try await syncService.syncListContents(at: relativePath) + } + + let item = try self.playbackService.getPlayableItem(from: libraryItem) + + playerManager.load(item, autoplay: autoplay) + + if recordAsLastBook { + await MainActor.run { + libraryService.setLibraryLastBook(with: item.relativePath) + } + } + } +} diff --git a/BookPlayer/Player/PlayerManager.swift b/BookPlayer/Player/PlayerManager.swift index 24025033e..7d70f24ae 100755 --- a/BookPlayer/Player/PlayerManager.swift +++ b/BookPlayer/Player/PlayerManager.swift @@ -13,40 +13,6 @@ import Foundation import MediaPlayer // swiftlint:disable:next file_length -/// sourcery: AutoMockable -public protocol PlayerManagerProtocol: AnyObject { - var currentItem: PlayableItem? { get set } - var currentSpeed: Float { get set } - var isPlaying: Bool { get } - var syncProgressDelegate: PlaybackSyncProgressDelegate? { get set } - - func load(_ item: PlayableItem, autoplay: Bool) - func hasLoadedBook() -> Bool - - func playPreviousItem() - func playNextItem(autoPlayed: Bool, shouldAutoplay: Bool) - func play() - func playPause() - func pause() - func stop() - func rewind() - func forward() - func skip(_ interval: TimeInterval) - func jumpTo(_ time: Double, recordBookmark: Bool) - func jumpToChapter(_ chapter: PlayableChapter) - func markAsCompleted(_ flag: Bool) - func setSpeed(_ newValue: Float) - func setBoostVolume(_ newValue: Bool) - - func currentSpeedPublisher() -> AnyPublisher - func isPlayingPublisher() -> AnyPublisher - func currentItemPublisher() -> AnyPublisher -} - -/// Delegate that hooks into the playback sequence -public protocol PlaybackSyncProgressDelegate: AnyObject { - func waitForSyncInProgress() async -} final class PlayerManager: NSObject, PlayerManagerProtocol { private let libraryService: LibraryServiceProtocol diff --git a/BookPlayer/Player/PlayerManagerProtocol.swift b/BookPlayer/Player/PlayerManagerProtocol.swift new file mode 100644 index 000000000..f9e1c84d2 --- /dev/null +++ b/BookPlayer/Player/PlayerManagerProtocol.swift @@ -0,0 +1,46 @@ +// +// PlayerManagerProtocol.swift +// BookPlayer +// +// Created by Gianni Carlo on 3/10/24. +// Copyright © 2024 Tortuga Power. All rights reserved. +// + +import BookPlayerKit +import Combine +import Foundation + +/// sourcery: AutoMockable +public protocol PlayerManagerProtocol: AnyObject { + var currentItem: PlayableItem? { get set } + var currentSpeed: Float { get set } + var isPlaying: Bool { get } + var syncProgressDelegate: PlaybackSyncProgressDelegate? { get set } + + func load(_ item: PlayableItem, autoplay: Bool) + func hasLoadedBook() -> Bool + + func playPreviousItem() + func playNextItem(autoPlayed: Bool, shouldAutoplay: Bool) + func play() + func playPause() + func pause() + func stop() + func rewind() + func forward() + func skip(_ interval: TimeInterval) + func jumpTo(_ time: Double, recordBookmark: Bool) + func jumpToChapter(_ chapter: PlayableChapter) + func markAsCompleted(_ flag: Bool) + func setSpeed(_ newValue: Float) + func setBoostVolume(_ newValue: Bool) + + func currentSpeedPublisher() -> AnyPublisher + func isPlayingPublisher() -> AnyPublisher + func currentItemPublisher() -> AnyPublisher +} + +/// Delegate that hooks into the playback sequence +public protocol PlaybackSyncProgressDelegate: AnyObject { + func waitForSyncInProgress() async +} diff --git a/BookPlayer/Services/ActionParserService.swift b/BookPlayer/Services/ActionParserService.swift index 8acb45742..46d5d4c54 100644 --- a/BookPlayer/Services/ActionParserService.swift +++ b/BookPlayer/Services/ActionParserService.swift @@ -41,7 +41,7 @@ class ActionParserService { appDelegate.pendingURLActions.append(action) guard - let watchConnectivityService = appDelegate.watchConnectivityService + let watchConnectivityService = appDelegate.coreServices?.watchService else { return } switch action.command { @@ -77,7 +77,7 @@ class ActionParserService { private class func handleRewindAction(_ action: Action) { guard - let playerManager = AppDelegate.shared?.playerManager + let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } @@ -93,7 +93,7 @@ class ActionParserService { private class func handleForwardAction(_ action: Action) { guard - let playerManager = AppDelegate.shared?.playerManager + let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } @@ -111,7 +111,7 @@ class ActionParserService { guard let valueString = action.getQueryValue(for: "start"), let chapterStart = Double(valueString), - let playerManager = AppDelegate.shared?.playerManager + let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } @@ -130,7 +130,7 @@ class ActionParserService { let roundedValue = round(speedRate * 100) / 100.0 guard - let playerManager = AppDelegate.shared?.playerManager + let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } @@ -144,7 +144,7 @@ class ActionParserService { let isOn = valueString == "true" guard - let playerManager = AppDelegate.shared?.playerManager + let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } @@ -188,7 +188,7 @@ class ActionParserService { private class func handlePlaybackToggleAction(_ action: Action) { guard - let playerManager = AppDelegate.shared?.playerManager + let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } @@ -208,7 +208,7 @@ class ActionParserService { private class func handlePauseAction(_ action: Action) { guard - let playerManager = AppDelegate.shared?.playerManager + let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } @@ -219,7 +219,7 @@ class ActionParserService { private class func handlePlayAction(_ action: Action) { guard - let playerManager = AppDelegate.shared?.playerManager + let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } diff --git a/BookPlayer/Services/CarPlayManager.swift b/BookPlayer/Services/CarPlayManager.swift index 3c21598e3..746292c47 100644 --- a/BookPlayer/Services/CarPlayManager.swift +++ b/BookPlayer/Services/CarPlayManager.swift @@ -7,8 +7,8 @@ // import BookPlayerKit -import Combine import CarPlay +import Combine class CarPlayManager: NSObject { var interfaceController: CPInterfaceController? @@ -27,7 +27,7 @@ class CarPlayManager: NSObject { // MARK: - Lifecycle - @MainActor + @MainActor func connect(_ interfaceController: CPInterfaceController) { self.interfaceController = interfaceController self.interfaceController?.delegate = self @@ -45,18 +45,14 @@ class CarPlayManager: NSObject { @MainActor func initializeDataIfNeeded() { guard - AppDelegate.shared?.dataManager == nil, AppDelegate.shared?.activeSceneDelegate == nil else { return } let dataInitializerCoordinator = DataInitializerCoordinator(alertPresenter: self) - dataInitializerCoordinator.onFinish = { [weak self] stack in - let services = AppDelegate.shared?.createCoreServicesIfNeeded(from: stack) - + dataInitializerCoordinator.onFinish = { [weak self] in self?.setRootTemplate() - - services?.watchService.startSession() + AppDelegate.shared?.coreServices?.watchService.startSession() } dataInitializerCoordinator.start() @@ -94,13 +90,14 @@ class CarPlayManager: NSObject { object: self, userInfo: [ "command": Command.boostVolume.rawValue, - "isOn": "\(!flag)" + "isOn": "\(!flag)", ] ) - let boostTitle = !flag - ? "\("settings_boostvolume_title".localized): \("active_title".localized)" - : "\("settings_boostvolume_title".localized): \("sleep_off_title".localized)" + let boostTitle = + !flag + ? "\("settings_boostvolume_title".localized): \("active_title".localized)" + : "\("settings_boostvolume_title".localized): \("sleep_off_title".localized)" self?.boostVolumeItem.setText(boostTitle) completion() @@ -109,7 +106,7 @@ class CarPlayManager: NSObject { func loadLibraryItems(at relativePath: String?) -> [SimpleLibraryItem] { guard - let libraryService = AppDelegate.shared?.libraryService + let libraryService = AppDelegate.shared?.coreServices?.libraryService else { return [] } return libraryService.fetchContents(at: relativePath, limit: nil, offset: nil) ?? [] @@ -118,10 +115,12 @@ class CarPlayManager: NSObject { // swiftlint:disable:next function_body_length func setupNowPlayingTemplate() { guard - let libraryService = AppDelegate.shared?.libraryService, - let playerManager = AppDelegate.shared?.playerManager + let coreServices = AppDelegate.shared?.coreServices else { return } + let libraryService = coreServices.libraryService + let playerManager = coreServices.playerManager + let prevButton = self.getPreviousChapterButton() let nextButton = self.getNextChapterButton() @@ -158,7 +157,7 @@ class CarPlayManager: NSObject { relativePath: currentItem.relativePath, type: .user ) { - AppDelegate.shared?.syncService?.scheduleSetBookmark( + coreServices.syncService.scheduleSetBookmark( relativePath: currentItem.relativePath, time: currentTime, note: nil @@ -177,7 +176,9 @@ class CarPlayManager: NSObject { self.interfaceController?.presentTemplate(alertTemplate, animated: true, completion: nil) } - CPNowPlayingTemplate.shared.updateNowPlayingButtons([prevButton, controlsButton, bookmarksButton, listButton, nextButton]) + CPNowPlayingTemplate.shared.updateNowPlayingButtons([ + prevButton, controlsButton, bookmarksButton, listButton, nextButton, + ]) } /// Setup root Tab bar template with the Recent and Library tabs @@ -213,7 +214,7 @@ class CarPlayManager: NSObject { /// Returns the library contents at a specified level func getLibraryContents(at relativePath: String? = nil) -> [CPListItem] { guard - let libraryService = AppDelegate.shared?.libraryService + let libraryService = AppDelegate.shared?.coreServices?.libraryService else { return [] } let items = libraryService.fetchContents(at: relativePath, limit: nil, offset: nil) ?? [] @@ -247,7 +248,7 @@ class CarPlayManager: NSObject { /// Reloads the recent items tab func reloadRecentItems() { guard - let libraryService = AppDelegate.shared?.libraryService + let libraryService = AppDelegate.shared?.coreServices?.libraryService else { return } let items = libraryService.getLastPlayedItems(limit: 20) ?? [] @@ -262,17 +263,32 @@ class CarPlayManager: NSObject { /// Handle playing the selected item func playItem(with relativePath: String) { - AppDelegate.shared?.loadPlayer( - relativePath, - autoplay: true, - showPlayer: { [weak self] in + Task { + let alertPresenter: AlertPresenter = self + do { + try await AppDelegate.shared?.coreServices?.playerLoaderService.loadPlayer( + relativePath, + autoplay: true + ) /// Avoid trying to show the now playing screen if it's already shown - if self?.interfaceController?.topTemplate != CPNowPlayingTemplate.shared { - self?.interfaceController?.pushTemplate(CPNowPlayingTemplate.shared, animated: true, completion: nil) + if self.interfaceController?.topTemplate != CPNowPlayingTemplate.shared { + self.interfaceController?.pushTemplate(CPNowPlayingTemplate.shared, animated: true, completion: nil) } - }, - alertPresenter: self - ) + } catch BPPlayerError.fileMissing { + alertPresenter.showAlert( + "file_missing_title".localized, + message: + "\("file_missing_description".localized)\n\(relativePath)", + completion: nil + ) + } catch { + alertPresenter.showAlert( + "error_title".localized, + message: error.localizedDescription, + completion: nil + ) + } + } } func formatSpeed(_ speed: Float) -> String { @@ -285,7 +301,7 @@ class CarPlayManager: NSObject { extension CarPlayManager { func hasChapter(before chapter: PlayableChapter?) -> Bool { guard - let playerManager = AppDelegate.shared?.playerManager, + let playerManager = AppDelegate.shared?.coreServices?.playerManager, let chapter = chapter else { return false } @@ -294,7 +310,7 @@ extension CarPlayManager { func hasChapter(after chapter: PlayableChapter?) -> Bool { guard - let playerManager = AppDelegate.shared?.playerManager, + let playerManager = AppDelegate.shared?.coreServices?.playerManager, let chapter = chapter else { return false } @@ -302,17 +318,19 @@ extension CarPlayManager { } func getPreviousChapterButton() -> CPNowPlayingImageButton { - let prevChapterImageName = self.hasChapter(before: AppDelegate.shared?.playerManager?.currentItem?.currentChapter) - ? "carplay.chevron.left" - : "carplay.chevron.left.2" + let prevChapterImageName = + self.hasChapter(before: AppDelegate.shared?.coreServices?.playerManager.currentItem?.currentChapter) + ? "carplay.chevron.left" + : "carplay.chevron.left.2" return CPNowPlayingImageButton( image: UIImage(named: prevChapterImageName)! ) { _ in - guard let playerManager = AppDelegate.shared?.playerManager else { return } + guard let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } if let currentChapter = playerManager.currentItem?.currentChapter, - let previousChapter = playerManager.currentItem?.previousChapter(before: currentChapter) { + let previousChapter = playerManager.currentItem?.previousChapter(before: currentChapter) + { playerManager.jumpToChapter(previousChapter) } else { playerManager.playPreviousItem() @@ -321,17 +339,19 @@ extension CarPlayManager { } func getNextChapterButton() -> CPNowPlayingImageButton { - let nextChapterImageName = self.hasChapter(after: AppDelegate.shared?.playerManager?.currentItem?.currentChapter) - ? "carplay.chevron.right" - : "carplay.chevron.right.2" + let nextChapterImageName = + self.hasChapter(after: AppDelegate.shared?.coreServices?.playerManager.currentItem?.currentChapter) + ? "carplay.chevron.right" + : "carplay.chevron.right.2" return CPNowPlayingImageButton( image: UIImage(named: nextChapterImageName)! ) { _ in - guard let playerManager = AppDelegate.shared?.playerManager else { return } + guard let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } if let currentChapter = playerManager.currentItem?.currentChapter, - let nextChapter = playerManager.currentItem?.nextChapter(after: currentChapter) { + let nextChapter = playerManager.currentItem?.nextChapter(after: currentChapter) + { playerManager.jumpToChapter(nextChapter) } else { playerManager.playNextItem(autoPlayed: false, shouldAutoplay: true) @@ -345,21 +365,27 @@ extension CarPlayManager { extension CarPlayManager { func showChapterListTemplate() { guard - let playerManager = AppDelegate.shared?.playerManager, + let playerManager = AppDelegate.shared?.coreServices?.playerManager, let chapters = playerManager.currentItem?.chapters else { return } let chapterItems = chapters.enumerated().map({ [weak self, playerManager] (index, chapter) -> CPListItem in - let chapterTitle = chapter.title == "" - ? String.localizedStringWithFormat("chapter_number_title".localized, index + 1) - : chapter.title - - let chapterDetail = String.localizedStringWithFormat("chapters_item_description".localized, TimeParser.formatTime(chapter.start), TimeParser.formatTime(chapter.duration)) + let chapterTitle = + chapter.title == "" + ? String.localizedStringWithFormat("chapter_number_title".localized, index + 1) + : chapter.title + + let chapterDetail = String.localizedStringWithFormat( + "chapters_item_description".localized, + TimeParser.formatTime(chapter.start), + TimeParser.formatTime(chapter.duration) + ) let item = CPListItem(text: chapterTitle, detailText: chapterDetail) if let currentChapter = playerManager.currentItem?.currentChapter, - currentChapter.index == chapter.index { + currentChapter.index == chapter.index + { item.isPlaying = true } @@ -369,7 +395,7 @@ extension CarPlayManager { object: self, userInfo: [ "command": Command.chapter.rawValue, - "start": "\(chapter.start)" + "start": "\(chapter.start)", ] ) completion() @@ -405,7 +431,7 @@ extension CarPlayManager { object: self, userInfo: [ "command": Command.chapter.rawValue, - "start": "\(bookmark.time)" + "start": "\(bookmark.time)", ] ) completion() @@ -417,11 +443,12 @@ extension CarPlayManager { func showBookmarkListTemplate() { guard - let playerManager = AppDelegate.shared?.playerManager, - let libraryService = AppDelegate.shared?.libraryService, - let currentItem = playerManager.currentItem + let coreServices = AppDelegate.shared?.coreServices, + let currentItem = coreServices.playerManager.currentItem else { return } + let libraryService = coreServices.libraryService + let playBookmarks = libraryService.getBookmarks(of: .play, relativePath: currentItem.relativePath) ?? [] let skipBookmarks = libraryService.getBookmarks(of: .skip, relativePath: currentItem.relativePath) ?? [] @@ -439,7 +466,11 @@ extension CarPlayManager { return self?.createBookmarkCPItem(from: bookmark, includeImage: false) } - let section1 = CPListSection(items: automaticItems, header: "bookmark_type_automatic_title".localized, sectionIndexTitle: nil) + let section1 = CPListSection( + items: automaticItems, + header: "bookmark_type_automatic_title".localized, + sectionIndexTitle: nil + ) let section2 = CPListSection(items: userItems, header: "bookmark_type_user_title".localized, sectionIndexTitle: nil) @@ -453,15 +484,16 @@ extension CarPlayManager { extension CarPlayManager { func showPlaybackControlsTemplate() { - let boostTitle = UserDefaults.standard.bool(forKey: Constants.UserDefaults.boostVolumeEnabled) - ? "\("settings_boostvolume_title".localized): \("active_title".localized)" - : "\("settings_boostvolume_title".localized): \("sleep_off_title".localized)" + let boostTitle = + UserDefaults.standard.bool(forKey: Constants.UserDefaults.boostVolumeEnabled) + ? "\("settings_boostvolume_title".localized): \("active_title".localized)" + : "\("settings_boostvolume_title".localized): \("sleep_off_title".localized)" boostVolumeItem.setText(boostTitle) let section1 = CPListSection(items: [boostVolumeItem]) - let currentSpeed = AppDelegate.shared?.playerManager?.currentSpeed ?? 1 + let currentSpeed = AppDelegate.shared?.coreServices?.playerManager.currentSpeed ?? 1 let formattedSpeed = formatSpeed(currentSpeed) let speedItems = self.getSpeedOptions() @@ -475,7 +507,7 @@ extension CarPlayManager { object: self, userInfo: [ "command": Command.speed.rawValue, - "rate": "\(roundedValue)" + "rate": "\(roundedValue)", ] ) @@ -485,7 +517,11 @@ extension CarPlayManager { return item }) - let section2 = CPListSection(items: speedItems, header: "\("player_speed_title".localized): \(formattedSpeed)", sectionIndexTitle: nil) + let section2 = CPListSection( + items: speedItems, + header: "\("player_speed_title".localized): \(formattedSpeed)", + sectionIndexTitle: nil + ) let listTemplate = CPListTemplate(title: "settings_controls_title".localized, sections: [section1, section2]) @@ -498,7 +534,7 @@ extension CarPlayManager { 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, - 4.0 + 4.0, ] } } @@ -506,8 +542,8 @@ extension CarPlayManager { extension CarPlayManager: CPInterfaceControllerDelegate {} extension CarPlayManager: AlertPresenter { - func showLoader() { } - func stopLoader() { } + func showLoader() {} + func stopLoader() {} public func showAlert(_ title: String? = nil, message: String? = nil, completion: (() -> Void)? = nil) { let okAction = CPAlertAction(title: "ok_button".localized, style: .default) { _ in diff --git a/BookPlayer/Services/ListSyncRefreshService.swift b/BookPlayer/Services/ListSyncRefreshService.swift index 9bbd703a3..8bd671b68 100644 --- a/BookPlayer/Services/ListSyncRefreshService.swift +++ b/BookPlayer/Services/ListSyncRefreshService.swift @@ -49,12 +49,28 @@ class ListSyncRefreshService: BPLogger { private func reloadLastBook(relativePath: String, alertPresenter: AlertPresenter) { let wasPlaying = playerManager.isPlaying playerManager.stop() - AppDelegate.shared?.loadPlayer( - relativePath, - autoplay: wasPlaying, - showPlayer: nil, - alertPresenter: alertPresenter - ) + + Task { + do { + try await AppDelegate.shared?.coreServices?.playerLoaderService.loadPlayer( + relativePath, + autoplay: wasPlaying + ) + } catch BPPlayerError.fileMissing { + alertPresenter.showAlert( + "file_missing_title".localized, + message: + "\("file_missing_description".localized)\n\(relativePath)", + completion: nil + ) + } catch { + alertPresenter.showAlert( + "error_title".localized, + message: error.localizedDescription, + completion: nil + ) + } + } } @MainActor @@ -63,11 +79,25 @@ class ListSyncRefreshService: BPLogger { guard playerManager.isPlaying == false else { return } await syncService.setLibraryLastBook(with: relativePath) - AppDelegate.shared?.loadPlayer( - relativePath, - autoplay: false, - showPlayer: nil, - alertPresenter: alertPresenter - ) + + do { + try await AppDelegate.shared?.coreServices?.playerLoaderService.loadPlayer( + relativePath, + autoplay: false + ) + } catch BPPlayerError.fileMissing { + alertPresenter.showAlert( + "file_missing_title".localized, + message: + "\("file_missing_description".localized)\n\(relativePath)", + completion: nil + ) + } catch { + alertPresenter.showAlert( + "error_title".localized, + message: error.localizedDescription, + completion: nil + ) + } } } diff --git a/BookPlayer/Settings/Player Settings Screen/PlayerSettingsViewController.swift b/BookPlayer/Settings/Player Settings Screen/PlayerSettingsViewController.swift index 25be3e813..dfd0f99e9 100644 --- a/BookPlayer/Settings/Player Settings Screen/PlayerSettingsViewController.swift +++ b/BookPlayer/Settings/Player Settings Screen/PlayerSettingsViewController.swift @@ -27,7 +27,8 @@ class PlayerSettingsViewController: UITableViewController, Storyboarded { private var disposeBag = Set() enum SettingsSection: Int { - case intervals = 0, rewind, sleepTimer, volume, speed, playerList, progressLabels + case intervals = 0 + case rewind, sleepTimer, volume, speed, playerList, progressLabels } let playerListPreferencePath = IndexPath(row: 0, section: SettingsSection.playerList.rawValue) @@ -51,19 +52,19 @@ class PlayerSettingsViewController: UITableViewController, Storyboarded { // Set initial switch positions smartRewindSwitch.setOn( - UserDefaults.standard.bool(forKey: Constants.UserDefaults.smartRewindEnabled), + UserDefaults.standard.bool(forKey: Constants.UserDefaults.smartRewindEnabled), animated: false ) autoSleepTimerSwitch.setOn( - UserDefaults.standard.bool(forKey: Constants.UserDefaults.autoTimerEnabled), + UserDefaults.standard.bool(forKey: Constants.UserDefaults.autoTimerEnabled), animated: false ) boostVolumeSwitch.setOn( - UserDefaults.standard.bool(forKey: Constants.UserDefaults.boostVolumeEnabled), + UserDefaults.standard.bool(forKey: Constants.UserDefaults.boostVolumeEnabled), animated: false ) globalSpeedSwitch.setOn( - UserDefaults.standard.bool(forKey: Constants.UserDefaults.globalSpeedEnabled), + UserDefaults.standard.bool(forKey: Constants.UserDefaults.globalSpeedEnabled), animated: false ) chapterTimeSwitch.setOn( @@ -112,13 +113,17 @@ class PlayerSettingsViewController: UITableViewController, Storyboarded { func showPlayerListOptionAlert(indexPath: IndexPath) { let sheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - sheet.addAction(UIAlertAction(title: "chapters_title".localized, style: .default) { [weak self] _ in - self?.viewModel.handleOptionSelected(.chapters) - }) + sheet.addAction( + UIAlertAction(title: "chapters_title".localized, style: .default) { [weak self] _ in + self?.viewModel.handleOptionSelected(.chapters) + } + ) - sheet.addAction(UIAlertAction(title: "bookmarks_title".localized, style: .default) { [weak self] _ in - self?.viewModel.handleOptionSelected(.bookmarks) - }) + sheet.addAction( + UIAlertAction(title: "bookmarks_title".localized, style: .default) { [weak self] _ in + self?.viewModel.handleOptionSelected(.bookmarks) + } + ) sheet.addAction(UIAlertAction(title: "cancel_button".localized, style: .cancel)) @@ -217,7 +222,7 @@ class PlayerSettingsViewController: UITableViewController, Storyboarded { @objc func boostVolumeToggleDidChange() { UserDefaults.standard.set(self.boostVolumeSwitch.isOn, forKey: Constants.UserDefaults.boostVolumeEnabled) - guard let playerManager = AppDelegate.shared?.playerManager else { return } + guard let playerManager = AppDelegate.shared?.coreServices?.playerManager else { return } playerManager.setBoostVolume(self.boostVolumeSwitch.isOn) } diff --git a/BookPlayer/Utils/CoreServices.swift b/BookPlayer/Utils/CoreServices.swift index 63e6910dc..7da91f31c 100644 --- a/BookPlayer/Utils/CoreServices.swift +++ b/BookPlayer/Utils/CoreServices.swift @@ -11,10 +11,11 @@ import Foundation struct CoreServices { let dataManager: DataManager - let accountService: AccountServiceProtocol - let syncService: SyncServiceProtocol - let libraryService: LibraryServiceProtocol - let playbackService: PlaybackServiceProtocol - let playerManager: PlayerManagerProtocol + let accountService: AccountService + let syncService: SyncService + let libraryService: LibraryService + let playbackService: PlaybackService + let playerManager: PlayerManager + let playerLoaderService: PlayerLoaderService let watchService: PhoneWatchConnectivityService } diff --git a/BookPlayerWidgets/Phone/BookPlaybackToggleIntent.swift b/BookPlayerWidgets/Phone/BookPlaybackToggleIntent.swift index 77003c7b0..11c1edefa 100644 --- a/BookPlayerWidgets/Phone/BookPlaybackToggleIntent.swift +++ b/BookPlayerWidgets/Phone/BookPlaybackToggleIntent.swift @@ -6,10 +6,10 @@ // Copyright © 2023 Tortuga Power. All rights reserved. // -import Foundation +import AVFoundation import AppIntents import BookPlayerKit -import AVFoundation +import Foundation @available(iOS 17.0, macOS 14.0, watchOS 10.0, *) struct BookPlaybackToggleIntent: AudioPlaybackIntent { @@ -17,10 +17,13 @@ struct BookPlaybackToggleIntent: AudioPlaybackIntent { static var title: LocalizedStringResource = .init("Toggle playback of book") @Parameter(title: "relativePath") - var relativePath: String? + var relativePath: String + + @Dependency + var playerLoaderService: PlayerLoaderService init() { - relativePath = nil + self.relativePath = "" } init(relativePath: String) { @@ -28,15 +31,11 @@ struct BookPlaybackToggleIntent: AudioPlaybackIntent { } func perform() async throws -> some IntentResult { - let url = WidgetUtils.getWidgetActionURL( - with: relativePath, - playbackToggle: true - ).absoluteString - - UserDefaults.sharedDefaults.set( - url, - forKey: Constants.UserDefaults.sharedWidgetActionURL - ) + if playerLoaderService.playerManager.currentItem?.relativePath == relativePath { + playerLoaderService.playerManager.playPause() + } else { + try await playerLoaderService.loadPlayer(relativePath, autoplay: true) + } return .result() } diff --git a/BookPlayerWidgets/Phone/BookStartPlaybackIntent.swift b/BookPlayerWidgets/Phone/BookStartPlaybackIntent.swift deleted file mode 100644 index 8fc2513e0..000000000 --- a/BookPlayerWidgets/Phone/BookStartPlaybackIntent.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// BookStartPlaybackIntent.swift -// BookPlayer -// -// Created by Gianni Carlo on 7/11/23. -// Copyright © 2023 Tortuga Power. All rights reserved. -// - -import Foundation -import AppIntents -import BookPlayerKit -import AVFoundation - -@available(iOS 17.0, macOS 14.0, watchOS 10.0, *) -struct BookStartPlaybackIntent: AudioPlaybackIntent { - - static var title: LocalizedStringResource = .init("Start playback of book") - - @Parameter(title: "relativePath") - var relativePath: String? - - init() { - relativePath = nil - } - - init(relativePath: String) { - self.relativePath = relativePath - } - - func perform() async throws -> some IntentResult { - let url = WidgetUtils.getWidgetActionURL( - with: relativePath, - autoplay: true, - timerSeconds: nil - ).absoluteString - - UserDefaults.sharedDefaults.set( - url, - forKey: Constants.UserDefaults.sharedWidgetActionURL - ) - - return .result() - } -} - diff --git a/Shared/Constants.swift b/Shared/Constants.swift index 7a6b7c051..0d89d3b78 100644 --- a/Shared/Constants.swift +++ b/Shared/Constants.swift @@ -50,9 +50,6 @@ public enum Constants { // One-time migrations public static let fileProtectionMigration = "userFileProtectionMigration" - /// Shared widget action URL - public static let sharedWidgetActionURL = "sharedWidgetActionURL" - /// Shared widget currently playing relative path public static let sharedWidgetNowPlayingPath = "sharedWidgetNowPlayingPath" diff --git a/Shared/Extensions/UserDefaults+BookPlayer.swift b/Shared/Extensions/UserDefaults+BookPlayer.swift index b74f03bed..9fe3329eb 100644 --- a/Shared/Extensions/UserDefaults+BookPlayer.swift +++ b/Shared/Extensions/UserDefaults+BookPlayer.swift @@ -11,14 +11,6 @@ import Foundation public extension UserDefaults { static var sharedDefaults = UserDefaults(suiteName: Constants.ApplicationGroupIdentifier)! - @objc dynamic var sharedWidgetActionURL: URL? { - guard - let widgetActionString = string(forKey: Constants.UserDefaults.sharedWidgetActionURL) - else { return nil } - - return URL(string: widgetActionString) - } - @objc dynamic var userSettingsAppIcon: String? { return string(forKey: Constants.UserDefaults.appIcon) } diff --git a/Shared/Services/LibraryService.swift b/Shared/Services/LibraryService.swift index 93c473a4c..38b50ddc4 100644 --- a/Shared/Services/LibraryService.swift +++ b/Shared/Services/LibraryService.swift @@ -136,7 +136,7 @@ public protocol LibraryServiceProtocol { } // swiftlint:disable force_cast -public final class LibraryService: LibraryServiceProtocol { +public final class LibraryService: LibraryServiceProtocol, @unchecked Sendable { let dataManager: DataManager /// Internal passthrough publisher for emitting metadata update events From 5f015fe4a920b78ea1200747b73df143989fdc88 Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Sat, 5 Oct 2024 11:56:52 -0500 Subject: [PATCH 12/18] Replace launch widget for last played widget --- BookPlayer.xcodeproj/project.pbxproj | 16 ++-- .../bookplayer.icon.symbolset/Contents.json | 12 --- .../bookplayer.icon.svg | 94 ------------------- BookPlayerWidgets/BookPlayerWidgets.swift | 2 +- .../Phone/LaunchAppControlWidgetView.swift | 43 --------- .../Phone/PlayLastControlWidgetView.swift | 26 +++++ 6 files changed, 37 insertions(+), 156 deletions(-) delete mode 100644 BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/Contents.json delete mode 100644 BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/bookplayer.icon.svg delete mode 100644 BookPlayerWidgets/Phone/LaunchAppControlWidgetView.swift create mode 100644 BookPlayerWidgets/Phone/PlayLastControlWidgetView.swift diff --git a/BookPlayer.xcodeproj/project.pbxproj b/BookPlayer.xcodeproj/project.pbxproj index 9e80bf0d3..450691dc4 100644 --- a/BookPlayer.xcodeproj/project.pbxproj +++ b/BookPlayer.xcodeproj/project.pbxproj @@ -388,8 +388,6 @@ 639720832CAB0C380045A4DB /* LastPlayedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720822CAB0C380045A4DB /* LastPlayedView.swift */; }; 639720852CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */; }; 6397208A2CAC5C870045A4DB /* LastPlayedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720892CAC5C870045A4DB /* LastPlayedModel.swift */; }; - 6397208C2CAC95040045A4DB /* LaunchAppControlWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6397208B2CAC95040045A4DB /* LaunchAppControlWidgetView.swift */; }; - 6397208D2CAC95040045A4DB /* LaunchAppControlWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6397208B2CAC95040045A4DB /* LaunchAppControlWidgetView.swift */; }; 6399F94D2AA03C6C00A5C8EA /* BPSKANManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */; }; 639AC9892AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; 639AC98A2AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; @@ -432,6 +430,10 @@ 63E893962CAFAB8F00946CD4 /* PlayerLoaderService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893942CAFAB8F00946CD4 /* PlayerLoaderService.swift */; }; 63E893982CAFAC7500946CD4 /* PlayerManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893972CAFAC7500946CD4 /* PlayerManagerProtocol.swift */; }; 63E893992CAFAC7500946CD4 /* PlayerManagerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893972CAFAC7500946CD4 /* PlayerManagerProtocol.swift */; }; + 63E893B02CB0AA7100946CD4 /* LastBookStartPlaybackIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6356F9C02AC823EE00B7A027 /* LastBookStartPlaybackIntent.swift */; }; + 63E893B22CB0AACE00946CD4 /* PlayLastControlWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893B12CB0AACE00946CD4 /* PlayLastControlWidgetView.swift */; }; + 63E893B32CB0AACE00946CD4 /* PlayLastControlWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E893B12CB0AACE00946CD4 /* PlayLastControlWidgetView.swift */; }; + 63E893B42CB1775500946CD4 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 419B375423B8D5A500128A8F /* Localizable.strings */; }; 63F1C7892BB91260006B164C /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 63F1C7882BB91259006B164C /* PrivacyInfo.xcprivacy */; }; 63F1C78B2BB91E21006B164C /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 63F1C78A2BB91E1B006B164C /* PrivacyInfo.xcprivacy */; }; 63F828572AED56FA00B5CE0C /* CornerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63F828562AED56FA00B5CE0C /* CornerView.swift */; }; @@ -1175,7 +1177,6 @@ 639720822CAB0C380045A4DB /* LastPlayedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedView.swift; sourceTree = ""; }; 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentBooksProvider.swift; sourceTree = ""; }; 639720892CAC5C870045A4DB /* LastPlayedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedModel.swift; sourceTree = ""; }; - 6397208B2CAC95040045A4DB /* LaunchAppControlWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchAppControlWidgetView.swift; sourceTree = ""; }; 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPSKANManager.swift; sourceTree = ""; }; 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPDownloadURLSession.swift; sourceTree = ""; }; 639E12C52B85AACF00C875F7 /* SyncTasksObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncTasksObject.swift; sourceTree = ""; }; @@ -1198,6 +1199,7 @@ 63E893912CAFA89000946CD4 /* BPPlayerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPPlayerError.swift; sourceTree = ""; }; 63E893942CAFAB8F00946CD4 /* PlayerLoaderService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerLoaderService.swift; sourceTree = ""; }; 63E893972CAFAC7500946CD4 /* PlayerManagerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerManagerProtocol.swift; sourceTree = ""; }; + 63E893B12CB0AACE00946CD4 /* PlayLastControlWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayLastControlWidgetView.swift; sourceTree = ""; }; 63F1C7882BB91259006B164C /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 63F1C78A2BB91E1B006B164C /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 63F828562AED56FA00B5CE0C /* CornerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerView.swift; sourceTree = ""; }; @@ -2310,7 +2312,7 @@ isa = PBXGroup; children = ( 6309F1252B0CF1C1002B86A4 /* BookPlaybackToggleIntent.swift */, - 6397208B2CAC95040045A4DB /* LaunchAppControlWidgetView.swift */, + 63E893B12CB0AACE00946CD4 /* PlayLastControlWidgetView.swift */, 4106413E258725F1008EB8D0 /* TimeListened */, 637DAB092AEB3E0D006DC2D1 /* WidgetEntries.swift */, 418445C2258AE11E0072DD13 /* WidgetUtils.swift */, @@ -3173,6 +3175,7 @@ buildActionMask = 2147483647; files = ( 63F1C78B2BB91E21006B164C /* PrivacyInfo.xcprivacy in Resources */, + 63E893B42CB1775500946CD4 /* Localizable.strings in Resources */, 416A29AC2569658300605395 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3465,6 +3468,7 @@ files = ( 418445C3258AE11E0072DD13 /* WidgetUtils.swift in Sources */, 4106414025872614008EB8D0 /* BarView.swift in Sources */, + 63E893B02CB0AA7100946CD4 /* LastBookStartPlaybackIntent.swift in Sources */, 630826062AF525F1002ACE0D /* SharedWidgetContainerView.swift in Sources */, 4106414925872699008EB8D0 /* TimeListenedSmallView.swift in Sources */, 417D996F256D73B400C3B753 /* Intents.intentdefinition in Sources */, @@ -3478,7 +3482,6 @@ 410641282579AA2F008EB8D0 /* TimeListenedWidgetView.swift in Sources */, 6309F1272B0CF658002B86A4 /* BookPlaybackToggleIntent.swift in Sources */, 630826032AF5225F002ACE0D /* CircularView.swift in Sources */, - 6397208C2CAC95040045A4DB /* LaunchAppControlWidgetView.swift in Sources */, 630826042AF522EA002ACE0D /* SharedWidgetEntry.swift in Sources */, 63E893962CAFAB8F00946CD4 /* PlayerLoaderService.swift in Sources */, 41064152258726D2008EB8D0 /* TimeListenedMediumView.swift in Sources */, @@ -3494,6 +3497,7 @@ 639720832CAB0C380045A4DB /* LastPlayedView.swift in Sources */, 639720852CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */, 630826072AF52831002ACE0D /* SharedWidget.swift in Sources */, + 63E893B32CB0AACE00946CD4 /* PlayLastControlWidgetView.swift in Sources */, 639720722CAAF8290045A4DB /* LastPlayedProvider.swift in Sources */, 630826022AF295AE002ACE0D /* CornerView.swift in Sources */, ); @@ -3605,6 +3609,7 @@ D6BA8F162A4CA94800C2BD9A /* StorageRowView.swift in Sources */, 9F3C436A284181690066D99A /* DataInitializerCoordinator.swift in Sources */, 9F3C436B284181C70066D99A /* AlertPresenter.swift in Sources */, + 63E893B22CB0AACE00946CD4 /* PlayLastControlWidgetView.swift in Sources */, 63B760FC2C33B77F00AA98C7 /* SupportProfileView.swift in Sources */, 9F00A6212950F44B005EA316 /* ImagePicker.swift in Sources */, 9F00A6242951F2F3005EA316 /* ItemDetailsFormViewModel.swift in Sources */, @@ -3657,7 +3662,6 @@ 9F5F13682978D9E100F061A0 /* ProfileSyncTasksStatusView.swift in Sources */, 41AD3DA7221C850F00DC41E1 /* IconCellView.swift in Sources */, 9FF710B92A213084006490E0 /* QueuedSyncTaskRowView.swift in Sources */, - 6397208D2CAC95040045A4DB /* LaunchAppControlWidgetView.swift in Sources */, 9FAB93742A53117C005B92B2 /* CompleteAccountView.swift in Sources */, 6304CF6A2B4C2AE800055285 /* SettingsAutoplayView.swift in Sources */, 4158388326EBD76A00F4A12B /* LibraryListCoordinator.swift in Sources */, diff --git a/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/Contents.json b/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/Contents.json deleted file mode 100644 index 35488c0fc..000000000 --- a/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - }, - "symbols" : [ - { - "filename" : "bookplayer.icon.svg", - "idiom" : "universal" - } - ] -} diff --git a/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/bookplayer.icon.svg b/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/bookplayer.icon.svg deleted file mode 100644 index 6ec43527a..000000000 --- a/BookPlayerWidgets/Assets.xcassets/bookplayer.icon.symbolset/bookplayer.icon.svg +++ /dev/null @@ -1,94 +0,0 @@ - - - - - -Weight/Scale Variations -Ultralight -Thin -Light -Regular -Medium -Semibold -Bold -Heavy -Black - - - - - - - - - - -Design Variations -Symbols are supported in up to nine weights and three scales. -For optimal layout with text and other symbols, vertically align -symbols with the adjacent text. - - - - - -Margins -Leading and trailing margins on the left and right side of each symbol -can be adjusted by modifying the x-location of the margin guidelines. -Modifications are automatically applied proportionally to all -scales and weights. - - - -Exporting -Symbols should be outlined when exporting to ensure the -design is preserved when submitting to Xcode. -Template v.6.0 -Requires Xcode 16 or greater -Generated from square.and.arrow.up.circle -Typeset at 100.0 points -Small -Medium -Large - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/BookPlayerWidgets/BookPlayerWidgets.swift b/BookPlayerWidgets/BookPlayerWidgets.swift index 9b11fe90b..16aa7f704 100644 --- a/BookPlayerWidgets/BookPlayerWidgets.swift +++ b/BookPlayerWidgets/BookPlayerWidgets.swift @@ -46,7 +46,7 @@ struct BookPlayerBundle: WidgetBundle { SharedIconWidget() } if #available(iOSApplicationExtension 18.0, *) { - LaunchAppButton() + PlayLastControlWidgetView() } #elseif os(watchOS) SharedWidget() diff --git a/BookPlayerWidgets/Phone/LaunchAppControlWidgetView.swift b/BookPlayerWidgets/Phone/LaunchAppControlWidgetView.swift deleted file mode 100644 index 8b1a66e6f..000000000 --- a/BookPlayerWidgets/Phone/LaunchAppControlWidgetView.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// LaunchAppControlWidgetView.swift -// BookPlayerWidgetsPhone -// -// Created by Gianni Carlo on 1/10/24. -// Copyright © 2024 Tortuga Power. All rights reserved. -// - -import AppIntents -import Foundation -import SwiftUI -import WidgetKit - -@available(iOSApplicationExtension 18.0, iOS 18.0, *) -struct LaunchAppButton: ControlWidget { - var body: some ControlWidgetConfiguration { - StaticControlConfiguration( - kind: "com.bookplayer.controlcenter.launchapp" - ) { - ControlWidgetButton(action: LaunchAppIntent()) { - Label("BookPlayer", image: "bookplayer.icon") - } - } - .displayName("BookPlayer") - } -} - -@available(iOSApplicationExtension 16, iOS 16.0, *) -struct LaunchAppIntent: OpenIntent { - static var title: LocalizedStringResource = "Launch App" - @Parameter(title: "Target") - var target: LaunchAppEnum -} - -@available(iOSApplicationExtension 16.0, iOS 16.0, *) -enum LaunchAppEnum: String, AppEnum { - case home - - static var typeDisplayRepresentation = TypeDisplayRepresentation("BookPlayer Home") - static var caseDisplayRepresentations = [ - LaunchAppEnum.home: DisplayRepresentation("Home") - ] -} diff --git a/BookPlayerWidgets/Phone/PlayLastControlWidgetView.swift b/BookPlayerWidgets/Phone/PlayLastControlWidgetView.swift new file mode 100644 index 000000000..c311e3c65 --- /dev/null +++ b/BookPlayerWidgets/Phone/PlayLastControlWidgetView.swift @@ -0,0 +1,26 @@ +// +// LastPlayControlWidgetView.swift +// BookPlayer +// +// Created by Gianni Carlo on 4/10/24. +// Copyright © 2024 Tortuga Power. All rights reserved. +// + +import AppIntents +import Foundation +import SwiftUI +import WidgetKit + +@available(iOSApplicationExtension 18.0, iOS 18.0, *) +struct PlayLastControlWidgetView: ControlWidget { + var body: some ControlWidgetConfiguration { + StaticControlConfiguration( + kind: "com.bookplayer.controlcenter.lastplayed" + ) { + ControlWidgetButton(action: LastBookStartPlaybackIntent()) { + Label("intent_lastbook_play_title", systemImage: "play.circle") + } + } + .displayName("intent_lastbook_play_title") + } +} From ef8d36d8d00fe192bc7be8062d2f58868cd4db5b Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Sat, 5 Oct 2024 16:20:10 -0500 Subject: [PATCH 13/18] Update tests --- BookPlayer/Utils/CoreServices.swift | 8 ++--- .../ItemListCoordinatorTests.swift | 1 + .../LoadingCoordinatorTests.swift | 2 +- .../Services/AccountServiceTests.swift | 6 +++- BookPlayerTests/StorageViewModelTests.swift | 30 ++++++++++++++++--- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/BookPlayer/Utils/CoreServices.swift b/BookPlayer/Utils/CoreServices.swift index 7da91f31c..4c67c759c 100644 --- a/BookPlayer/Utils/CoreServices.swift +++ b/BookPlayer/Utils/CoreServices.swift @@ -11,11 +11,11 @@ import Foundation struct CoreServices { let dataManager: DataManager - let accountService: AccountService - let syncService: SyncService + let accountService: AccountServiceProtocol + let syncService: SyncServiceProtocol let libraryService: LibraryService - let playbackService: PlaybackService - let playerManager: PlayerManager + let playbackService: PlaybackServiceProtocol + let playerManager: PlayerManagerProtocol let playerLoaderService: PlayerLoaderService let watchService: PhoneWatchConnectivityService } diff --git a/BookPlayerTests/Coordinators/ItemListCoordinatorTests.swift b/BookPlayerTests/Coordinators/ItemListCoordinatorTests.swift index 0de8dab83..15be2ebcd 100644 --- a/BookPlayerTests/Coordinators/ItemListCoordinatorTests.swift +++ b/BookPlayerTests/Coordinators/ItemListCoordinatorTests.swift @@ -66,6 +66,7 @@ class LibraryListCoordinatorTests: XCTestCase { XCTAssertTrue(presentingController.horizontalStack == ["ItemListViewController", "ItemListViewController"]) } + @MainActor func testShowPlayer() { self.libraryListCoordinator.showPlayer() XCTAssert(presentingController.verticalStack == ["PlayerViewController"]) diff --git a/BookPlayerTests/Coordinators/LoadingCoordinatorTests.swift b/BookPlayerTests/Coordinators/LoadingCoordinatorTests.swift index cf065a643..e34893474 100644 --- a/BookPlayerTests/Coordinators/LoadingCoordinatorTests.swift +++ b/BookPlayerTests/Coordinators/LoadingCoordinatorTests.swift @@ -25,7 +25,7 @@ class LoadingCoordinatorTests: XCTestCase { } func testFinishedLoadingSequence() { - self.loadingCoordinator.didFinishLoadingSequence(coreDataStack: CoreDataStack(testPath: "/dev/null")) + self.loadingCoordinator.didFinishLoadingSequence() XCTAssertNotNil(self.loadingCoordinator.getMainCoordinator()) } } diff --git a/BookPlayerTests/Services/AccountServiceTests.swift b/BookPlayerTests/Services/AccountServiceTests.swift index 603077d6a..3f0d47c30 100644 --- a/BookPlayerTests/Services/AccountServiceTests.swift +++ b/BookPlayerTests/Services/AccountServiceTests.swift @@ -21,7 +21,11 @@ class AccountServiceTests: XCTestCase { DataTestUtils.clearFolderContents(url: DataManager.getProcessedFolderURL()) let dataManager = DataManager(coreDataStack: CoreDataStack(testPath: "/dev/null")) self.mockKeychain = KeychainServiceProtocolMock() - self.sut = AccountService(dataManager: dataManager, keychain: self.mockKeychain) + self.sut = AccountService( + dataManager: dataManager, + client: NetworkClientMock(mockedResponse: Empty()), + keychain: self.mockKeychain + ) } private func setupBlankAccount() { diff --git a/BookPlayerTests/StorageViewModelTests.swift b/BookPlayerTests/StorageViewModelTests.swift index e3ea906bf..b84efe3d4 100644 --- a/BookPlayerTests/StorageViewModelTests.swift +++ b/BookPlayerTests/StorageViewModelTests.swift @@ -46,9 +46,6 @@ final class StorageViewModelMissingFileTests: XCTestCase { } func testSetup(with filename: String) { - /// Avoid making the second onboarding network call - AppDelegate.shared?.accountService = AccountServiceMock(account: nil) - let bookContents = "bookcontents".data(using: .utf8)! let documentsURL = DataManager.getDocumentsFolderURL() @@ -68,9 +65,34 @@ final class StorageViewModelMissingFileTests: XCTestCase { let dataManager = DataManager(coreDataStack: CoreDataStack(testPath: self.testPath)) let libraryService = LibraryService(dataManager: dataManager) _ = libraryService.getLibrary() + let syncService = SyncServiceProtocolMock() + let playbackService = PlaybackServiceProtocolMock() + let playerManager = PlayerManagerProtocolMock() + + /// Avoid making the second onboarding network call + AppDelegate.shared?.coreServices = CoreServices( + dataManager: dataManager, + accountService: AccountServiceMock(account: nil), + syncService: syncService, + libraryService: libraryService, + playbackService: playbackService, + playerManager: playerManager, + playerLoaderService: PlayerLoaderService( + syncService: syncService, + libraryService: libraryService, + playbackService: playbackService, + playerManager: playerManager + ), + watchService: PhoneWatchConnectivityService( + libraryService: libraryService, + playbackService: playbackService, + playerManager: playerManager + ) + ) + self.viewModel = StorageViewModel( libraryService: libraryService, - syncService: SyncServiceProtocolMock(), + syncService: syncService, folderURL: self.directoryURL ) } From b1af3b3d0a6e9780bdb4f53933dd108ac0561925 Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Sat, 5 Oct 2024 23:13:41 -0500 Subject: [PATCH 14/18] Fix remote play command logic --- BookPlayer/AppDelegate.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/BookPlayer/AppDelegate.swift b/BookPlayer/AppDelegate.swift index b28bcb4ba..99b0072dd 100644 --- a/BookPlayer/AppDelegate.swift +++ b/BookPlayer/AppDelegate.swift @@ -214,7 +214,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate, BPLogger { return .commandFailed } - playerManager.play() + let wasPlaying = playerManager.isPlaying + playerManager.playPause() + + if wasPlaying, + UIApplication.shared.applicationState == .background + { + self?.scheduleAppRefresh() + } return .success } From 5f5793898e38372db5981af25d5ebcf5deab5d6c Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Sun, 6 Oct 2024 22:41:01 -0500 Subject: [PATCH 15/18] Filter out chapters with 0 duration --- Shared/Services/PlaybackService.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Shared/Services/PlaybackService.swift b/Shared/Services/PlaybackService.swift index fe0eb953a..2541b0a66 100644 --- a/Shared/Services/PlaybackService.swift +++ b/Shared/Services/PlaybackService.swift @@ -199,7 +199,7 @@ public final class PlaybackService: PlaybackServiceProtocol { func getPlayableChapters(book: SimpleLibraryItem) throws -> [PlayableChapter] { guard - let chapters = self.libraryService.getChapters(from: book.relativePath) + var chapters = self.libraryService.getChapters(from: book.relativePath) else { throw BookPlayerError.runtimeError( String.localizedStringWithFormat( @@ -209,6 +209,9 @@ public final class PlaybackService: PlaybackServiceProtocol { ) } + /// Ignore chapters that don't have the duration set properly + chapters = chapters.filter { $0.duration > 0 } + guard !chapters.isEmpty else { return [ PlayableChapter( From f9c17d962aaeffa09e63424006659ced36a82a1b Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Sun, 6 Oct 2024 22:41:39 -0500 Subject: [PATCH 16/18] Fix navigation for volumes with nested chapters --- BookPlayer/Player/PlayerManager.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BookPlayer/Player/PlayerManager.swift b/BookPlayer/Player/PlayerManager.swift index 7d70f24ae..54ee0c582 100755 --- a/BookPlayer/Player/PlayerManager.swift +++ b/BookPlayer/Player/PlayerManager.swift @@ -444,7 +444,8 @@ final class PlayerManager: NSObject, PlayerManagerProtocol { if currentTime >= currentItem.currentChapter.end || currentTime < currentItem.currentChapter.start, let newChapter = currentItem.getChapter(at: currentTime), - newChapter != currentItem.currentChapter + newChapter != currentItem.currentChapter, + !currentItem.isBoundBook || newChapter.chapterOffset != 0 { /// Avoid setting the same chapter, as it would publish an update event currentItem.currentChapter = newChapter From 2e93aa669d3dc3f2e0d39f3a3a3ef845c871ac2d Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Sun, 6 Oct 2024 23:00:56 -0500 Subject: [PATCH 17/18] Set app version --- BookPlayer.xcodeproj/project.pbxproj | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/BookPlayer.xcodeproj/project.pbxproj b/BookPlayer.xcodeproj/project.pbxproj index 450691dc4..c617de598 100644 --- a/BookPlayer.xcodeproj/project.pbxproj +++ b/BookPlayer.xcodeproj/project.pbxproj @@ -4166,7 +4166,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerIntents"; @@ -4200,7 +4200,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerIntents"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -4232,7 +4232,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerIntents"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -4268,7 +4268,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp"; @@ -4309,7 +4309,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -4347,7 +4347,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -4516,7 +4516,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerWidgetUI"; @@ -4554,7 +4554,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerWidgetUI"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -4590,7 +4590,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerWidgetUI"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -4743,7 +4743,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = BookPlayer; PROVISIONING_PROFILE_SPECIFIER = "$(BP_PROVISIONING_MAIN)"; @@ -4781,7 +4781,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = BookPlayer; PROVISIONING_PROFILE_SPECIFIER = "$(BP_PROVISIONING_MAIN)"; @@ -5003,7 +5003,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp.widgets"; @@ -5041,7 +5041,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp.widgets"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5077,7 +5077,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).watchkitapp.widgets"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5116,7 +5116,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerShareExtension"; @@ -5156,7 +5156,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5194,7 +5194,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER).BookPlayerShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5286,7 +5286,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 5.3.6; + MARKETING_VERSION = 5.4.0; PRODUCT_BUNDLE_IDENTIFIER = "$(BP_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = BookPlayer; PROVISIONING_PROFILE_SPECIFIER = "$(BP_PROVISIONING_MAIN)"; From 4e66760a2e6bbf8c8e9f2cfb67ea337cd9babdcc Mon Sep 17 00:00:00 2001 From: Gianni Carlo Date: Sun, 6 Oct 2024 23:31:23 -0500 Subject: [PATCH 18/18] Remove unused class --- BookPlayer.xcodeproj/project.pbxproj | 18 +--- .../Deprecated/RecentBooksProvider.swift | 82 ------------------- .../RecentBooksWidgetView.swift | 0 3 files changed, 3 insertions(+), 97 deletions(-) delete mode 100644 BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksProvider.swift rename BookPlayerWidgets/Phone/{Recent/Deprecated => RecentBooks}/RecentBooksWidgetView.swift (100%) diff --git a/BookPlayer.xcodeproj/project.pbxproj b/BookPlayer.xcodeproj/project.pbxproj index c617de598..60e78d8af 100644 --- a/BookPlayer.xcodeproj/project.pbxproj +++ b/BookPlayer.xcodeproj/project.pbxproj @@ -386,7 +386,6 @@ 639720742CAAFB010045A4DB /* WidgetLibraryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720732CAAFB010045A4DB /* WidgetLibraryItem.swift */; }; 639720752CAAFB010045A4DB /* WidgetLibraryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720732CAAFB010045A4DB /* WidgetLibraryItem.swift */; }; 639720832CAB0C380045A4DB /* LastPlayedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720822CAB0C380045A4DB /* LastPlayedView.swift */; }; - 639720852CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */; }; 6397208A2CAC5C870045A4DB /* LastPlayedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639720892CAC5C870045A4DB /* LastPlayedModel.swift */; }; 6399F94D2AA03C6C00A5C8EA /* BPSKANManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */; }; 639AC9892AD9F1D50053AFC6 /* BPDownloadURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */; }; @@ -1175,7 +1174,6 @@ 639720712CAAF8290045A4DB /* LastPlayedProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedProvider.swift; sourceTree = ""; }; 639720732CAAFB010045A4DB /* WidgetLibraryItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetLibraryItem.swift; sourceTree = ""; }; 639720822CAB0C380045A4DB /* LastPlayedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedView.swift; sourceTree = ""; }; - 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentBooksProvider.swift; sourceTree = ""; }; 639720892CAC5C870045A4DB /* LastPlayedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastPlayedModel.swift; sourceTree = ""; }; 6399F94C2AA03C6C00A5C8EA /* BPSKANManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPSKANManager.swift; sourceTree = ""; }; 639AC9882AD9F1D50053AFC6 /* BPDownloadURLSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BPDownloadURLSession.swift; sourceTree = ""; }; @@ -2253,21 +2251,12 @@ path = LastPlayed; sourceTree = ""; }; - 639720772CAAFCAF0045A4DB /* Recent */ = { - isa = PBXGroup; - children = ( - 639720782CAAFCBB0045A4DB /* Deprecated */, - ); - path = Recent; - sourceTree = ""; - }; - 639720782CAAFCBB0045A4DB /* Deprecated */ = { + 639720772CAAFCAF0045A4DB /* RecentBooks */ = { isa = PBXGroup; children = ( 41ADD6D92570AC6300660C64 /* RecentBooksWidgetView.swift */, - 639720842CABB0D00045A4DB /* RecentBooksProvider.swift */, ); - path = Deprecated; + path = RecentBooks; sourceTree = ""; }; 63B2303B2B8CCDDB00AEECED /* Realm */ = { @@ -2317,7 +2306,7 @@ 637DAB092AEB3E0D006DC2D1 /* WidgetEntries.swift */, 418445C2258AE11E0072DD13 /* WidgetUtils.swift */, 639720702CAAF8180045A4DB /* LastPlayed */, - 639720772CAAFCAF0045A4DB /* Recent */, + 639720772CAAFCAF0045A4DB /* RecentBooks */, ); path = Phone; sourceTree = ""; @@ -3495,7 +3484,6 @@ 630826162AF6CABD002ACE0D /* SharedIconWidgetEntry.swift in Sources */, 9FF383D52A40F97000BBAC11 /* MappingModel_v8_to_v9.xcmappingmodel in Sources */, 639720832CAB0C380045A4DB /* LastPlayedView.swift in Sources */, - 639720852CABB0D00045A4DB /* RecentBooksProvider.swift in Sources */, 630826072AF52831002ACE0D /* SharedWidget.swift in Sources */, 63E893B32CB0AACE00946CD4 /* PlayLastControlWidgetView.swift in Sources */, 639720722CAAF8290045A4DB /* LastPlayedProvider.swift in Sources */, diff --git a/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksProvider.swift b/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksProvider.swift deleted file mode 100644 index ec7ff78fa..000000000 --- a/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksProvider.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// RecentBooksProvider.swift -// BookPlayerWidgetsPhone -// -// Created by Gianni Carlo on 30/9/24. -// Copyright © 2024 Tortuga Power. All rights reserved. -// - -import BookPlayerKit -import SwiftUI -import WidgetKit - -struct RecentBooksProvider: TimelineProvider { - let numberOfBooks = 4 - - typealias Entry = LibraryEntry - - func placeholder(in context: Context) -> LibraryEntry { - return LibraryEntry( - date: Date(), - items: [ - SimpleLibraryItem.previewItem(title: "Last played"), - SimpleLibraryItem.previewItem(title: "Book title"), - SimpleLibraryItem.previewItem(title: "Book title"), - SimpleLibraryItem.previewItem(title: "Book title"), - ] - ) - } - - func getSnapshot( - in context: Context, - completion: @escaping (LibraryEntry) -> Void - ) { - Task { - do { - let entry = try await getEntryForTimeline( - context: context - ) - completion(entry) - } catch { - completion(placeholder(in: context)) - } - } - } - - func getTimeline( - in context: Context, - completion: @escaping (Timeline) -> Void - ) { - Task { - do { - let entry = try await getEntryForTimeline(context: context) - - completion(Timeline(entries: [entry], policy: .never)) - } catch { - completion(Timeline(entries: [], policy: .never)) - } - } - } - - func getEntryForTimeline(context: Context) async throws -> LibraryEntry { - let stack = try await DatabaseInitializer().loadCoreDataStack() - let dataManager = DataManager(coreDataStack: stack) - let libraryService = LibraryService(dataManager: dataManager) - - guard - let items = libraryService.getLastPlayedItems(limit: numberOfBooks) - else { - throw BookPlayerError.emptyResponse - } - - let theme = libraryService.getLibraryCurrentTheme() ?? SimpleTheme.getDefaultTheme() - - let entry = LibraryEntry( - date: Date(), - items: items, - theme: theme - ) - - return entry - } -} diff --git a/BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksWidgetView.swift b/BookPlayerWidgets/Phone/RecentBooks/RecentBooksWidgetView.swift similarity index 100% rename from BookPlayerWidgets/Phone/Recent/Deprecated/RecentBooksWidgetView.swift rename to BookPlayerWidgets/Phone/RecentBooks/RecentBooksWidgetView.swift