From a4bf3dc51cf2f84f8f9546b5f694f42e21256ba6 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Fri, 8 Sep 2023 14:19:20 +0200 Subject: [PATCH] add sheet for mounts --- Habitica/res/drawable-hdpi/icon_lock.png | Bin 0 -> 418 bytes Habitica/res/drawable-hdpi/shop_locked.png | Bin 1557 -> 0 bytes Habitica/res/drawable-mdpi/icon_lock.png | Bin 0 -> 331 bytes Habitica/res/drawable-xhdpi/icon_lock.png | Bin 0 -> 495 bytes Habitica/res/drawable-xhdpi/shop_locked.png | Bin 2233 -> 0 bytes Habitica/res/drawable-xxhdpi/icon_lock.png | Bin 0 -> 664 bytes Habitica/res/drawable-xxhdpi/shop_locked.png | Bin 3579 -> 0 bytes Habitica/res/drawable/shop_locked.xml | 14 ++ Habitica/res/layout/activity_armoire.xml | 68 ++++--- .../res/layout/task_form_task_scheduling.xml | 15 +- Habitica/res/values/strings.xml | 1 + .../habitica/ui/activities/ArmoireActivity.kt | 45 ++++- .../social/party/PartyDetailFragment.kt | 2 +- .../ui/viewHolders/MountViewHolder.kt | 29 ++- .../ui/viewHolders/ShopItemViewHolder.kt | 3 +- .../habitica/ui/views/BackgroundScene.kt | 73 +++++++ .../habitica/ui/views/HabiticaButton.kt | 2 +- .../ui/views/stable/MountBottomSheet.kt | 179 ++++++++++++++++++ .../habitica/ui/views/stable/MountView.kt | 48 +++++ .../ui/views/stable/PetBottomSheet.kt | 57 +----- .../tasks/form/TaskSchedulingControls.kt | 9 +- .../habitica/extensions/DataBindingUtils.kt | 1 + .../common/habitica/helpers/Animations.kt | 4 +- .../common/habitica/views/ValueBar.kt | 2 +- version.properties | 2 +- 25 files changed, 441 insertions(+), 113 deletions(-) create mode 100644 Habitica/res/drawable-hdpi/icon_lock.png delete mode 100644 Habitica/res/drawable-hdpi/shop_locked.png create mode 100644 Habitica/res/drawable-mdpi/icon_lock.png create mode 100644 Habitica/res/drawable-xhdpi/icon_lock.png delete mode 100644 Habitica/res/drawable-xhdpi/shop_locked.png create mode 100644 Habitica/res/drawable-xxhdpi/icon_lock.png delete mode 100644 Habitica/res/drawable-xxhdpi/shop_locked.png create mode 100644 Habitica/res/drawable/shop_locked.xml create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/BackgroundScene.kt create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/MountBottomSheet.kt create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/MountView.kt diff --git a/Habitica/res/drawable-hdpi/icon_lock.png b/Habitica/res/drawable-hdpi/icon_lock.png new file mode 100644 index 0000000000000000000000000000000000000000..e83bc8636377d515a83083879f12d42790f96c91 GIT binary patch literal 418 zcmV;T0bTxyP)lVRkOGSGqoBY9EfX*T86gYA#uw$HDUfh@9bXh3I7@P$ zu=K;2)(sIs{SxBhnrYN%y?B%Vmijap< zbh)UVE5Km2H8r(CEuD+Ym&qN5y5Fsx95`WaMwo;2^&^2bG4tsvR(|axjT6Z_&D*3D zKOitX!T}QZd$)C`a=P0oG^_MoyMA+fH8rt5VH4X2n7+I(x7dPh$<_Q?Y40;eI6@np z#j1cq;ql#Q0QSt%~x!KRIAi;@y>V_ZtKex!bs;FF0>)5J&7v`=j!CiTHIF{y1| zT5a0YhbE*6)|gg&kkZgvbwNWBV_H{a6$NCMU0^?EXKv43neBq??#%KLf646Kojr5! zf6lq*+&csC0>i-~@QwLg3Q=l6fpYB0n)ri)9|#N)h1|5+ZC#Khy2Zr>amqp9xV`l42l=0u-#a!kQvG=!H-WZ&EE3lK$fe5!yfpfj|)YZuCPa6rOYbzGoQBW)svk zY{1s6xjz}?Hf$P!`4W;mhcU0pwdDP)wWCld1U=o?Ar_0Jv=PvY&dqP?5*UtzY8?(o zFZ-^}ISylf7<6#$&%T5(CZc*>CA{{=t58u<3g#SB{Co_<+<)s1=)oWu_Nd=yawRxQis6;@>!7ZFBM5?!uw{ohVk$5($Ft23t46`@kJY@4x8#418N6?MHi(|8F zd&8P-d0wnwZ9J?>EXIK#Xu2>t5m`W6Q3Abv?&D98+qZAi_?C&S61YtBMfg=UljOv1MI#^|!FXc!!5uw{72cM)g`;P}2WO zSy@@6xq08ulm5UNSV4S#|CwFy?D_$PMO0yo`OmFfNlA%GlBB$w?wcJ3ld%DonW!WU zY}!=c0wEPIq^Ch4Ye1#Sm9~(dW#h0IdbN>AKQLL>Yr_&ipB`l*j2F?X??%X*M=bV-5y(bkL0;?+BM?zSH~^g)mGj4(zeJTNf8Y8g#8w$?YB z9D0%9U5fZN2-jt!0iRg~Z26r#cjh1$SS*%!e;9T}6h#^5lx#AY zVnszov8t*n1#gatqObyRvj<_>jjhO*KzR0C!VZ#TlNJ8~fq1e45m6BO00000NkvXX Hu0mjf72xi4 diff --git a/Habitica/res/drawable-mdpi/icon_lock.png b/Habitica/res/drawable-mdpi/icon_lock.png new file mode 100644 index 0000000000000000000000000000000000000000..181b86336fe82d30b6982d4cda355260cc41c240 GIT binary patch literal 331 zcmeAS@N?(olHy`uVBq!ia0vp^U^WLEkTt>lKP!;pEbxddW?Nd)P5;OXKRQo&doaFO$n1JB-=^Z$1>_B~*;Y6`Fq z@p{Q}iL-=d?gA0bzX30}@*Z&9X!g}s)7H#BvV zBky$nb$NKGMvYh5Xt9ZZU#_x4OfMs$^(v%77{XXXd%MGt6ClQ?snp^nM;ljWgvCk*Y@vao4aua}v#LeVY5$mlnd XpX1^@s6F&7Tg00009a7bBm000&x z000&x0ZCFM@Bjb+0drDELIAGL9O(c600d`2O+f$vv5yPTNb_Fu$?Au;=U2pX-;5hu~AyQR--sml~0LEV$t^46Y z!0{k*k&DO#8P+97Ua57xWhQU~!XHbyArXeOIE0P@YyE7Asivb!K*j@ zDI2L|AVg4tkW+X?I=#M^PAz4a`f*nCv(?m1@`;2Q=GmJ!}ZUIz$}g-^*+1{nB20-rtK-Ve(J-3WQT-Yi_~8#0q$ z=6J4(0XUFAR>B8!aF;Q5mk0hVlJ2zI?LN=}DHHNKy;Y23O^k!`#Rw#^kWV?r9k=J& zJ0S&VCNxI`pbGQ^2mOr6Ejc+kt)Ky_3888^n8Z%&P9z43#02hrRKHyHvx;|*D2T`revx0>scCggSdn`B_Eso04IWO2Zsc01k8$zHIe%AqIXJZ{fv zoca!|Bsi`$JKJ6litrL+Q3=hG@f}-nGP8@>?RL3;ztl87@%2c?`eC5}qJqB>ja|2qwut%E`<56ym5~TtcIxqw9@E(?y)_fYk}#^vvUL6%`eEVoxkk zIZ`zPZ)nnsOjs0QVqy|JZm-hT30YQa+HWC_Ko$%r(lMC&AVu`ve*oj7E``i|WM-yA z@%kbtD9ndc5fY_c`T4n*=8r`YBI!7t?pA^4e-0WkGcyBSpLZjXsYT~mtrmD~$18ZW zf>tmFm$P&1)f~so*-{jtfq{Vy>9&k7KqH9Ets7l<3?wyQ4^n}tnTi5O!JSBd&W1=j zR;#TEQb6~A{uh@_W@ZMgU29)3PIKv+RA922UWa*t5h4u~8^3MawqqP{nnIiLQ780$ zF%UIYQ1~ot+rD+yW{UEazpxmF$$9EXq}FC!h6t6co_gS1<@giu&)Z@Ub#l`DxQ(I9v zR5vgQTot5%`3oeJY+9diZplVRRDaSx38}zh6uwI)Lv4jnOG^u9FdM%EDIgpUNB42h zA(HX_Vv(#9NeF>2udAz5xESbPXJ;qh@XPnIwC1l5haW8%BehZkQdd$_E#P_nC8yJ= ztezuLAq*JF-p6h+s01y9>_-p0w*3`!5O&qqVPR%4H#esQo1!A7s;VkM3mHQ1{~v%} z=)K<$TEKJsb0sAuvnq$u0qii)h}eiA-hQ(fJf5dE70suh9kA08fNq;j*K0STe+8-TAV#9+AF;c$@ZF=b;l zo6XEW>A&`j#qtZ#8EUo%KBro4yuJG-3m2{u z2Wl%4+OT1ReB#6jU+vpJ{+HQo+6gHjmAym@#E^LX$dM!7EnBucCDh*DF0Wg+E<8Fm z@3%A$PW-^&1jCN#N?vaV}w?sJoz`z*=8lpTDA|B%PwWj#(lD$t(3(E`$7e^-5rk;1^T`kvqz&Z$@DOZm{b0Pk{o}XQ zdcEa@%-962>CmA=z1R(+o0ekd2(be=i8VGhvhMC~?&{U6Q=2!xa1G<6*YQo5VFf{C zIy*1c9z1xk2fH(sm6ama;^f$Q3Ckk2wY9>PD_6)L+m0XqUHPu+s#EA93trgH2hAuQD@rZ5@x6V&!U(z^z5;l>-c!eZ zee~!jfBnRTFE)T*6(f>KSOZC>630nwpO>=oK*~2w_MT%*eT03Czuz!5HDx4XsES6En1JfR@87?_u(G1EEITK=6weizP39cTp`vmO`N^d|;khmgLqJVpY`Ud0%_y~ETNU3*N zCj}+Wu4C6piq!rjOZLuqKJU)%>>7Az5K0mb!rE{5rU8-qJOaf}ZrpLpZ%s;sDJDD@ zQ%9o26QFMPk}-(;oN#pDx8ij%*9wn<@CZmg=-V0!K{1i)zw5R?=6cx-X)mvxBosjt zcYp|&PZP(trGRXrzc{(lw+&Q6#?O?yXA)~55l@)rBide#4Lm6_Pr0q&H zrKUT2%(&z3Q<2xMt<35AIK(Cp@eHkX*XDoN-S@EpM!{Fl)Xumk+>-v#g~T(pA9UXi zu}xtmY}>1cD8aoA^`r34C_TA0Rai<3Z>q5Te?x666lGBYt8jXVtF6Akxrh3SOjsY% y$JjBcCZ~S}*fEk&!0GRZg7qxC4f==v{_qcy^~k+5U`sFn0000WTuk`I%yh}m_$cSV#h~)1fvqIuSN)*h~<57fE?Uox8KilM*;8PfZYQOpP8H8 z+uP^oKHul>w?s3TK{z4M6v6fD*W+W&vFUtA7XD-m`l*AI{!gc~^Ll!EdOJ-4ObT)B z?d=xw(qpnB=Lv$aND*ie6JrVKV1YUWh0ZIAa$Xd~V@!* zTp=nT4Iv0jBq`fPQT!xaBR+8SI0%TCIs2Xq*@qamezc zqoP6DQ#6gi+0v(m9`PAVx@FAO$he4WYqNjNf7v3s1Hh5?d_rRUeFPDX0b}xUs!wZe zE4x!j1NfO1anAYfSbg4Dh!gCs9YxdKJOe@zo^Dh9b?69*W&9hhO|2V5gY*X7$xwtB z6Rei4p(M(o5GOP?Hf9)&rpk~z7}FOWZjbA}l#~?PXylD(s!$pVbtdibcYrj&Vw8*@ zhqB|SKCZR7wRl=2w^~6E^3-P@#TtYD2({JK)n!IU#e7R)gvafs&dzRfI(yacW^*LP z#zvFDXrwU0Z?d&)vH^E61Us^%q(oT1{`n#b13;F|R!=wU8_3zy8*m?xm!3I?5)v&; zrkQkx#UL3FWgn*?`CULdp|a2wL#A?zRw%Qw1eXW)}9#2U7LxJg8b0{NY4(Sbd zuj|JtsVPSS1&Uy%DmFK_z9)&|uSq9BWtHbHk-cqvV=u{fSt&PnzOE+BjnHF>*2EPd z5f=`%fwZqGzE*wNL;&->|AEE2lGohQWSuu}o_#oZw?$Pr!??KkS4c-xSJ@^^8h~@) zTzbNqkotMw}ZGzbx^)u25P)0D)Qq%6D`|}syMj8MGE?==s-6z<2^;Dh7U|Nmz zY_RH7;!sxM)6&wyKPWnyX=A|c=2?+6Kj&T=4cG_!210XFE9nJ6GCa6%-#%%us~b=p z7=8KWmlGsW$|ar9)!7wrd-mK+j*N!U4p;X{50byx?K=87f$~aAONZ3zDshM!#l^)m zckbLg(h)r)_^42ka#zxr&aD;F)3cT{M+1^m|7Mu!+O=ziS+k-aBpnf~I?%#DdEB8@ z9^-|4=r~9iKpId}Q-d@_H^p@ZF;n2;g{!0moKB~1b*vXj<>np%UcF}<&^Pc0B2HrOmJSg=63b?X+^HCJ5qHCxD?4=n&+cfGcrw1*JK&mrvI zy&Jww0egx+TJU-tX$(CR(_m<7Y$2@yZfrK&fOV?D0n&51Toal{5)45r1+GQ4z|ETt zAzyQ%xclzAh5jOe1f(NEK|z7Qp;q(BcOzlpqWPo+0uiS-AU4q-Ucn}BaL^1!1vpbp zb;XJm?p85t>~Z%Hs!f2|r3 z5uq@7a<9{QkR}mGj01fp6Wla71#ZBRkGTIQz<|Tykh$kHW3I!{+S+^&fq@k_5D(N2 zu480a_8ezHc{ztu{I$KmF^9n#v8=4j#QBQ( z#PJhvMMXtFK^ownpZ_bYZ6yGMIxByw%_zXFo}Qh{mOZeZSDp3s^)6m|vE4sdLq$bJ zN>o&o+}+*nwbj@@B#jUo7enDjY>al-tf{HqX)>9-adB}VY@iV`;NbelAOtBTB_)FG z*<5+1@>64kX&Frr=*MA#O*pYIZ@wlanpc)@+;dOneeBzMxt-L@9I0wU4|7Nlj+=Cf z(P)%8f_Sfd^UW6002ulU$6Pi)GBW3AR@XK(G`t=kAMfR8s;bR5KBKDcwz(smni#ky zQ&o5V-1$#TkrDZ%0Wf*6x~i7+#JrrjDsfr>YRk&XSOT@N751^HJRC%2|L;SHgSqnf zs(A9`$q0_Bkvn$$y&x}l;YXwq(3wSByUQ{0DPDsS6BkWstg=vM1B8liYpS1Fvu4d+ zUUg1N24d_O3>Bc$nh^2xO)D$iDa7HKv=LK*;*XS7m;p6KrC-nDAg zssr4kbhFyL+;)>komhxOW%1(0o}Qi_5BodMM<4Gk;uNKmz9aB>z4f0T`s{T)JECb) zQj&~}WB7gn2WT(^#!k`01F-JbUMs1syKy5dv(Kjj{##$aW%K6E*YWJ&AduRCV6)C) zwh~to5f+OjvbD9YA`!e03aPhO{=P!MQs~i^>^=>4*?B|9gy@MeII}t|_g-KJcT)86f zC_j33?!?4|<2gAC9?`pw4L3Ll)R&j<`qhaOC))b@`dl$FG486WDi1i|QZ(Q(K?kAz zT@xO?_RN|!%WXEBU8SX^wL5qIqYw_1?hxQvKICWGvSo`6q-ADidNMLHJZ!G=NN*5I zBb^jOVdy{Iym^!CcDp))efsq2u2^%-p#=-4zw)3o2;tRNU$t?K?qY$cYJ2$Mhh-iz z9dUqu)UiNcpinD{=H_OO(5473$xItJZcP8>6Ho5u3L}lCA)vGmKG?bT%{TvIgI{Cx zB_}7lP$3}w80~#kX|xN##(fj3l>-M3C>ZhQP))47Zi^-E(D$?N&5;a-sh`yjg0t6I zQBqP=`2PDl8vUekFmUJQ=6bhn+cqj`K**!dzV3;@RfVymqr=37uZb^c|P|4SCzt*vztNjK0sP^b@ixzZ7@Qfp@b6xxB%yM>IHFO_6gpVKUw)k#p$n} zn94x|_jZQwv7q3=Vs%P5 zlu}=Fb4%&gzm~qcfB$|vlLgY;$kmXevQP7JrG&1>m}YB@>f-_d%7f2qY;06IJ3AF7 zPKk|;CC>R=+jo>zL_|iFXWx?*$2XWmlL&{Sv;4!IAN+RR`sY5oc=6&b-lRG-Zkr+P zaC12|F4BOB%&}kAcIvk$YFF^0>k! zR;xQFC&#;M*DkdoIbPD#V@U(}N6DB#n7)LZkIOUzr!7WKG9@NY;^?bRx7fIGQ`(Py zn4ix%)6xiY5ZTvBn8gnAc;rk~A?Hg21Y$Zpn~ZwxM<0FE^4O}!a;z!I zX))1JshktW86+u|@Fs!6!rZL-SdLe)GlaI~+hnhr=Q914$r`NmQ5EhaXO2Li}$p3Vt$?T=R0o zYpA14Oc3uY``4i|Cd-SZUtyTbhH-+yV+C44yC%I4{`Nb-1mdRAnt>0LxT~y^g%8xn zyI}5$fbVQl#Htbzow1Ec7~+Gl&c|cy*S}q6Ukbu7Z9^q2F)>kQg~?f2Su*CsoIQJ1 zGlkvuoTMZCFUCTFSVDz(ABz2(c=hU40WVyDEKZ`;w1~|Z+eH7mZ$27kQpx`B7{26& zgM#S@yo6cGoRrHPB^7RSE9hSPUsNL<5ta$R{uk|p{_fV^002ovPDHLkV1mJ^ B*h&BZ diff --git a/Habitica/res/drawable/shop_locked.xml b/Habitica/res/drawable/shop_locked.xml new file mode 100644 index 000000000..59cfd6f02 --- /dev/null +++ b/Habitica/res/drawable/shop_locked.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/Habitica/res/layout/activity_armoire.xml b/Habitica/res/layout/activity_armoire.xml index 4c448b16a..34e05f5e7 100644 --- a/Habitica/res/layout/activity_armoire.xml +++ b/Habitica/res/layout/activity_armoire.xml @@ -85,6 +85,7 @@ android:textStyle="bold" android:textSize="28sp" android:gravity="center" + android:alpha="0" android:textColor="@color/text_primary"/> - - + android:layout_height="65dp" + android:paddingStart="24dp" + android:paddingEnd="18dp"> + + + - + android:text="@string/subscription_benefit_armoire_sub" + android:textColor="@color/white" + style="@style/Body2" + android:gravity="center" + android:paddingHorizontal="48dp" + android:layout_marginTop="6dp"/> + + android:textColor="@color/text_secondary" + android:paddingVertical="2dp"/> - \ No newline at end of file + diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index f374adcf3..66ce8ca01 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -1457,6 +1457,7 @@ Invited to Group Plan \@Mentions in Group Plans Subscribe to hold on with 1HP! + Your subscription gives you an extra chance at the Armoire! diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt index 0bb373701..edc53c761 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt @@ -36,6 +36,7 @@ import com.habitrpg.common.habitica.helpers.launchCatching import com.plattysoft.leonids.ParticleSystem import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.MainScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch import java.util.Locale @@ -173,8 +174,36 @@ class ArmoireActivity : BaseActivity() { } private fun giveUserArmoire(): Boolean { + binding.iconWrapper.post { + binding.iconView.bitmap = null + Animations.circularHide(binding.iconWrapper) + } + binding.titleView.animate().apply { + alpha(0f) + duration = 300 + startDelay = 0 + start() + } + binding.subtitleView.animate().apply { + alpha(0f) + duration = 300 + startDelay = 0 + start() + } + + binding.goldView.animate().apply { + alpha(0f) + start() + } + val user = userViewModel.user.value ?: return true val currentGold = user.stats?.gp ?: return true + if (binding.adButton.visibility == View.VISIBLE) { + binding.adButton.state = AdButton.State.UNAVAILABLE + binding.adButton.visibility = View.INVISIBLE + } else if (binding.openArmoireSubscriberWrapper.visibility == View.VISIBLE) { + binding.openArmoireSubscriberWrapper.visibility = View.INVISIBLE + } lifecycleScope.launch(ExceptionHandler.coroutine()) { userRepository.updateUser("stats.gp", currentGold + 100) val buyResponse = @@ -185,27 +214,25 @@ class ArmoireActivity : BaseActivity() { buyResponse.armoire["dropText"] ?: "", buyResponse.armoire["value"] ?: "" ) - if (binding.adButton.visibility == View.VISIBLE) { - binding.adButton.state = AdButton.State.UNAVAILABLE - binding.adButton.visibility = View.INVISIBLE - } else if (binding.openArmoireSubscriberWrapper.visibility == View.VISIBLE) { - binding.openArmoireSubscriberWrapper.visibility = View.INVISIBLE - } hasAnimatedChanges = false gold = null + startAnimation(false) } return false } override fun onResume() { super.onResume() - startAnimation() + lifecycleScope.launchCatching { + delay(500L) + startAnimation(true) + } } - private fun startAnimation() { + private fun startAnimation(decreaseGold: Boolean) { val gold = gold?.toInt() if (hasAnimatedChanges) return - if (gold != null) { + if (gold != null && decreaseGold) { /** * We are adding 100 as the gold is already "deducted" before the animation starts, * and animating to show the current user's gold amount. diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt index 408921dc9..b8621fef8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyDetailFragment.kt @@ -291,7 +291,7 @@ class PartyDetailFragment : BaseFragment() { binding?.questParticipationView?.setTextColor( ContextCompat.getColor( it, - R.color.text_quad + R.color.text_ternary ) ) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt index 0bc6bae05..5bb436e8d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt @@ -1,5 +1,6 @@ package com.habitrpg.android.habitica.ui.viewHolders +import android.app.Activity import android.content.res.Resources import android.graphics.drawable.BitmapDrawable import android.view.View @@ -11,7 +12,11 @@ import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.models.inventory.Mount import com.habitrpg.android.habitica.ui.menu.BottomSheetMenu import com.habitrpg.android.habitica.ui.menu.BottomSheetMenuItem +import com.habitrpg.android.habitica.ui.views.showAsBottomSheet +import com.habitrpg.android.habitica.ui.views.stable.MountBottomSheet +import com.habitrpg.android.habitica.ui.views.stable.PetBottomSheet import com.habitrpg.common.habitica.extensions.DataBindingUtils +import dagger.hilt.android.internal.managers.ViewComponentManager class MountViewHolder(parent: ViewGroup, private val onEquip: ((String) -> Unit)?) : androidx.recyclerview.widget.RecyclerView.ViewHolder(parent.inflate(R.layout.mount_overview_item)), View.OnClickListener { private var binding: MountOverviewItemBinding = MountOverviewItemBinding.bind(itemView) @@ -51,16 +56,20 @@ class MountViewHolder(parent: ViewGroup, private val onEquip: ((String) -> Unit) if (!owned) { return } - val menu = BottomSheetMenu(itemView.context) - menu.setTitle(animal?.text) - menu.setImage("stable_Mount_Icon_" + animal?.animal + "-" + animal?.color) - - val hasCurrentMount = currentMount.equals(animal?.key) - val labelId = if (hasCurrentMount) R.string.unequip else R.string.equip - menu.addMenuItem(BottomSheetMenuItem(resources.getString(labelId))) - menu.setSelectionRunnable { - animal?.let { onEquip?.invoke(it.key ?: "") } + val context = itemView.context + animal?.let { pet -> + (if (context is ViewComponentManager.FragmentContextWrapper) { + context.baseContext + } else { + context + }as Activity).showAsBottomSheet { + MountBottomSheet( + pet, + currentMount.equals(animal?.key), + onEquip, + it + ) + } } - menu.show() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ShopItemViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ShopItemViewHolder.kt index 1e9f9d804..15af97893 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ShopItemViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/ShopItemViewHolder.kt @@ -72,8 +72,7 @@ class ShopItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), Vi binding.itemDetailIndicator.background = AppCompatResources.getDrawable(context, R.drawable.pill_bg_gray) binding.itemDetailIndicator.visibility = View.VISIBLE - } - if (item.locked) { + } else if (item.locked) { binding.itemDetailIndicator.background = AppCompatResources.getDrawable(context, R.drawable.shop_locked) binding.itemDetailIndicator.visibility = View.VISIBLE } else if (isLimited) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/BackgroundScene.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/BackgroundScene.kt new file mode 100644 index 000000000..68b596bf8 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/BackgroundScene.kt @@ -0,0 +1,73 @@ +package com.habitrpg.android.habitica.ui.views + +import android.graphics.Bitmap +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.ImageShader +import androidx.compose.ui.graphics.Paint +import androidx.compose.ui.graphics.TileMode +import androidx.compose.ui.graphics.asAndroidBitmap +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.graphics.drawscope.drawIntoCanvas +import androidx.compose.ui.graphics.nativeCanvas +import androidx.compose.ui.res.imageResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex +import com.habitrpg.android.habitica.R +import java.util.Calendar + +@Composable +private fun getBackgroundPainter(): ImageBitmap { + val calendar = Calendar.getInstance() + val month = calendar.get(Calendar.MONTH) + return ImageBitmap.imageResource( + when (month) { + Calendar.JANUARY -> R.drawable.stable_tile_janurary + Calendar.FEBRUARY -> R.drawable.stable_tile_february + Calendar.MARCH -> R.drawable.stable_tile_march + Calendar.APRIL -> R.drawable.stable_tile_april + Calendar.MAY -> R.drawable.stable_tile_may + Calendar.JUNE -> R.drawable.stable_tile_june + Calendar.JULY -> R.drawable.stable_tile_july + Calendar.AUGUST -> R.drawable.stable_tile_august + Calendar.SEPTEMBER -> R.drawable.stable_tile_september + Calendar.OCTOBER -> R.drawable.stable_tile_october + Calendar.NOVEMBER -> R.drawable.stable_tile_november + Calendar.DECEMBER -> R.drawable.stable_tile_december + else -> R.drawable.stable_tile_may + } + ) +} + +@Composable +fun BackgroundScene() { + val image = getBackgroundPainter() + Canvas( + modifier = Modifier + .height(124.dp) + .fillMaxWidth() + .zIndex(1f), onDraw = { + val bitmap = Bitmap.createScaledBitmap( + image.asAndroidBitmap(), + image.width.dp.roundToPx(), + 124.dp.roundToPx(), + false + ) + val paint = Paint().asFrameworkPaint().apply { + isAntiAlias = true + shader = ImageShader( + bitmap.asImageBitmap(), + TileMode.Repeated, + TileMode.Repeated + ) + } + drawIntoCanvas { + it.nativeCanvas.drawPaint(paint) + } + paint.reset() + }) +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaButton.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaButton.kt index affa2b626..ff9d5b67b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaButton.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/HabiticaButton.kt @@ -31,8 +31,8 @@ fun HabiticaButton( Box( contentAlignment = Alignment.Center, modifier = modifier - .clickable { onClick() } .background(background, HabiticaTheme.shapes.medium) + .clickable { onClick() } .fillMaxWidth() .padding(contentPadding) ) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/MountBottomSheet.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/MountBottomSheet.kt new file mode 100644 index 000000000..0fe089a15 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/MountBottomSheet.kt @@ -0,0 +1,179 @@ +package com.habitrpg.android.habitica.ui.views.stable + +import com.habitrpg.android.habitica.models.inventory.Animal +import com.habitrpg.android.habitica.models.inventory.Mount +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.CubicBezierEasing +import androidx.compose.animation.core.FastOutSlowInEasing +import androidx.compose.animation.core.LinearOutSlowInEasing +import androidx.compose.animation.core.RepeatMode +import androidx.compose.animation.core.StartOffset +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.keyframes +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.scaleIn +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material.LinearProgressIndicator +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.scale +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.res.imageResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.zIndex +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.ui.theme.HabiticaTheme +import com.habitrpg.android.habitica.ui.views.BackgroundScene +import com.habitrpg.android.habitica.ui.views.HabiticaButton +import java.util.Calendar +import kotlin.math.sin + +@Composable +private fun getBackgroundPainter(): ImageBitmap { + val calendar = Calendar.getInstance() + val month = calendar.get(Calendar.MONTH) + return ImageBitmap.imageResource( + when (month) { + Calendar.JANUARY -> R.drawable.stable_tile_janurary + Calendar.FEBRUARY -> R.drawable.stable_tile_february + Calendar.MARCH -> R.drawable.stable_tile_march + Calendar.APRIL -> R.drawable.stable_tile_april + Calendar.MAY -> R.drawable.stable_tile_may + Calendar.JUNE -> R.drawable.stable_tile_june + Calendar.JULY -> R.drawable.stable_tile_july + Calendar.AUGUST -> R.drawable.stable_tile_august + Calendar.SEPTEMBER -> R.drawable.stable_tile_september + Calendar.OCTOBER -> R.drawable.stable_tile_october + Calendar.NOVEMBER -> R.drawable.stable_tile_november + Calendar.DECEMBER -> R.drawable.stable_tile_december + else -> R.drawable.stable_tile_may + } + ) +} + +@Composable +fun MountBottomSheet( + mount: Mount, + isCurrentMount: Boolean, + onEquip: ((String) -> Unit)?, + onDismiss: () -> Unit, + modifier: Modifier = Modifier +) { + val infiniteTransition = rememberInfiniteTransition() + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = modifier.padding(horizontal = 22.dp) + ) { + Text( + mount.text ?: "", + fontSize = 16.sp, + fontWeight = FontWeight.Medium, + color = HabiticaTheme.colors.textTertiary + ) + Box( + modifier = Modifier + .padding(top = 9.dp, bottom = 16.dp) + .fillMaxWidth() + .height(124.dp) + .clip(HabiticaTheme.shapes.medium) + ) { + BackgroundScene() + + val regularPosition = 33f + val highJump = 22f + val lowJump = 30f + val position by if (isAnimalFlying(mount)) { + infiniteTransition.animateFloat( + initialValue = 24f, + targetValue = 16f, + animationSpec = infiniteRepeatable( + tween( + 2500, + easing = CubicBezierEasing(0.3f, 0.0f, 0.2f, 1.0f) + ), RepeatMode.Reverse + ), + label = "animalPosition" + ) + } else { + infiniteTransition.animateFloat( + initialValue = regularPosition, + targetValue = highJump, + animationSpec = infiniteRepeatable(animation = keyframes { + durationMillis = 6000 + regularPosition at 0 with LinearOutSlowInEasing + highJump at 150 with LinearOutSlowInEasing + regularPosition at 300 with FastOutSlowInEasing + regularPosition at 1800 with FastOutSlowInEasing + lowJump at 1850 with LinearOutSlowInEasing + regularPosition at 1900 with LinearOutSlowInEasing + regularPosition at 2100 with FastOutSlowInEasing + lowJump at 2200 with LinearOutSlowInEasing + regularPosition at 2350 with LinearOutSlowInEasing + regularPosition at 6000 + }, RepeatMode.Restart, StartOffset(1500)), label = "animalPosition" + ) + } + MountView(mount, modifier = Modifier + .offset(0.dp, position.dp) + .size(68.dp) + .align(Alignment.TopCenter) + .zIndex(2f) + ) + } + HabiticaButton( + background = HabiticaTheme.colors.tintedUiSub, + color = Color.White, + contentPadding = PaddingValues(12.dp), + onClick = { + onEquip?.invoke(mount.key) + onDismiss() + }) { + if (isCurrentMount) { + Text(stringResource(id = R.string.unequip)) + } else { + Text(stringResource(id = R.string.equip)) + } + } + } +} + +fun isAnimalFlying(animal: Animal): Boolean { + if (listOf( + "FlyingPig", + "Bee" + ).contains(animal.animal) + ) return true + return listOf( + "Ghost", + "Cupid", + "Fairy", + "SolarSystem", + "Vampire" + ).contains(animal.color) +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/MountView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/MountView.kt new file mode 100644 index 000000000..68c66e2f2 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/MountView.kt @@ -0,0 +1,48 @@ +package com.habitrpg.android.habitica.ui.views.stable + +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.asAndroidBitmap +import androidx.compose.ui.viewinterop.AndroidView +import com.habitrpg.android.habitica.models.inventory.Mount +import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.views.PixelArtView + +class MountView @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null +) : FrameLayout(context, attrs) { + + private val bodyView: PixelArtView = PixelArtView(context) + private val headView: PixelArtView = PixelArtView(context) + + fun setMount(key: String) { + bodyView.loadImage("Mount_Body_$key") + headView.loadImage("Mount_Head_$key") + } + + init { + addView(bodyView) + addView(headView) + } +} + +@Composable +fun MountView(mount: Mount, modifier: Modifier = Modifier) { + MountView(mount.key, modifier) +} + +@Composable +fun MountView(mountKey: String, modifier: Modifier = Modifier) { + AndroidView( + modifier = modifier, + factory = { context -> + MountView(context) + }, + update = { view -> + view.setMount(mountKey) + } + ) +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/PetBottomSheet.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/PetBottomSheet.kt index d34b1ff36..7ba70dbae 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/PetBottomSheet.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/stable/PetBottomSheet.kt @@ -55,6 +55,7 @@ import androidx.compose.ui.graphics.asAndroidBitmap import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.graphics.nativeCanvas +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.imageResource import androidx.compose.ui.res.stringResource @@ -67,38 +68,16 @@ import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.models.inventory.Food import com.habitrpg.android.habitica.models.inventory.Pet import com.habitrpg.android.habitica.ui.theme.HabiticaTheme +import com.habitrpg.android.habitica.ui.views.BackgroundScene import com.habitrpg.android.habitica.ui.views.HabiticaButton import com.habitrpg.android.habitica.ui.views.PixelArtView +import com.habitrpg.common.habitica.extensions.getThemeColor import com.habitrpg.common.habitica.helpers.MainNavigationController import com.habitrpg.common.habitica.helpers.launchCatching import com.habitrpg.shared.habitica.models.responses.FeedResponse import kotlinx.coroutines.delay -import java.util.Calendar import kotlin.math.sin -@Composable -private fun getBackgroundPainter(): ImageBitmap { - val calendar = Calendar.getInstance() - val month = calendar.get(Calendar.MONTH) - return ImageBitmap.imageResource( - when (month) { - Calendar.JANUARY -> R.drawable.stable_tile_janurary - Calendar.FEBRUARY -> R.drawable.stable_tile_february - Calendar.MARCH -> R.drawable.stable_tile_march - Calendar.APRIL -> R.drawable.stable_tile_april - Calendar.MAY -> R.drawable.stable_tile_may - Calendar.JUNE -> R.drawable.stable_tile_june - Calendar.JULY -> R.drawable.stable_tile_july - Calendar.AUGUST -> R.drawable.stable_tile_august - Calendar.SEPTEMBER -> R.drawable.stable_tile_september - Calendar.OCTOBER -> R.drawable.stable_tile_october - Calendar.NOVEMBER -> R.drawable.stable_tile_november - Calendar.DECEMBER -> R.drawable.stable_tile_december - else -> R.drawable.stable_tile_may - } - ) -} - @Composable private fun getFoodPainter(petColor: String): ImageBitmap { return ImageBitmap.imageResource( @@ -152,7 +131,6 @@ fun PetBottomSheet( fontWeight = FontWeight.Medium, color = HabiticaTheme.colors.textTertiary ) - val image = getBackgroundPainter() Box( modifier = Modifier .padding(top = 9.dp, bottom = 16.dp) @@ -160,30 +138,7 @@ fun PetBottomSheet( .height(124.dp) .clip(HabiticaTheme.shapes.medium) ) { - Canvas( - modifier = Modifier - .height(124.dp) - .fillMaxWidth() - .zIndex(1f), onDraw = { - val bitmap = Bitmap.createScaledBitmap( - image.asAndroidBitmap(), - image.width.dp.roundToPx(), - 124.dp.roundToPx(), - false - ) - val paint = Paint().asFrameworkPaint().apply { - isAntiAlias = true - shader = ImageShader( - bitmap.asImageBitmap(), - TileMode.Repeated, - TileMode.Repeated - ) - } - drawIntoCanvas { - it.nativeCanvas.drawPaint(paint) - } - paint.reset() - }) + BackgroundScene() this@Column.AnimatedVisibility( visible = showFeedResponse, modifier = Modifier @@ -298,7 +253,7 @@ fun PetBottomSheet( modifier = Modifier.padding(bottom = 16.dp) ) { HabiticaButton( - colorResource(id = R.color.offset_background_30), + Color(LocalContext.current.getThemeColor(R.attr.colorTintedBackgroundOffset)), HabiticaTheme.colors.textPrimary, onClick = { if (ownsSaddles) { @@ -324,7 +279,7 @@ fun PetBottomSheet( } } HabiticaButton( - colorResource(id = R.color.offset_background_30), + Color(LocalContext.current.getThemeColor(R.attr.colorTintedBackgroundOffset)), HabiticaTheme.colors.textPrimary, onClick = { coroutineScope.launchCatching { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt index 368f95f43..fca57d36d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt @@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.ui.views.tasks.form import android.app.DatePickerDialog import android.content.Context import android.content.DialogInterface +import android.content.res.ColorStateList import android.icu.text.MessageFormat import android.os.Build import android.text.TextUtils @@ -321,14 +322,14 @@ class TaskSchedulingControls @JvmOverloads constructor( } private fun styleButtonAsActive(button: TextView) { - button.setTextColor(context.getThemeColor(R.attr.colorTintedBackground)) - button.background.mutate().setTint(tintColor) + button.setTextColor(context.getThemeColor(R.attr.tintedUiDetails)) + button.backgroundTintList = ColorStateList.valueOf(context.getThemeColor(R.attr.tintedUiMain)) button.contentDescription = toContentDescription(button.text, true) } private fun styleButtonAsInactive(button: TextView) { - button.setTextColor(context.getThemeColor(R.attr.colorPrimaryDark)) - button.background.mutate().setTint(context.getThemeColor(R.attr.colorTintedBackgroundOffset)) + button.setTextColor(context.getThemeColor(R.attr.textColorTintedSecondary)) + button.backgroundTintList = ColorStateList.valueOf(context.getThemeColor(R.attr.colorTintedBackgroundOffset)) button.contentDescription = toContentDescription(button.text, false) } diff --git a/common/src/main/java/com/habitrpg/common/habitica/extensions/DataBindingUtils.kt b/common/src/main/java/com/habitrpg/common/habitica/extensions/DataBindingUtils.kt index c19de6748..2e4322fd1 100644 --- a/common/src/main/java/com/habitrpg/common/habitica/extensions/DataBindingUtils.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/extensions/DataBindingUtils.kt @@ -153,6 +153,7 @@ object DataBindingUtils { tempMap["shield_special_ks2019"] = "gif" tempMap["weapon_special_ks2019"] = "gif" tempMap["Pet-Gryphon-Gryphatrice"] = "gif" + tempMap["stable_Pet-Gryphon-Gryphatrice"] = "gif" tempMap["Mount_Head_Gryphon-Gryphatrice"] = "gif" tempMap["Mount_Body_Gryphon-Gryphatrice"] = "gif" tempMap["background_clocktower"] = "gif" diff --git a/common/src/main/java/com/habitrpg/common/habitica/helpers/Animations.kt b/common/src/main/java/com/habitrpg/common/habitica/helpers/Animations.kt index b746c08a7..478c02369 100644 --- a/common/src/main/java/com/habitrpg/common/habitica/helpers/Animations.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/helpers/Animations.kt @@ -61,11 +61,13 @@ object Animations { anim.start() } - fun circularHide(view: View) { + fun circularHide(view: View, duration: Long = 300) { val cx = view.width / 2 val cy = view.height / 2 val initialRadius = Math.hypot(cx.toDouble(), cy.toDouble()).toFloat() val anim = ViewAnimationUtils.createCircularReveal(view, cx, cy, initialRadius, 0f) + anim.duration = duration + anim.interpolator = AccelerateInterpolator() anim.doOnEnd { view.visibility = View.INVISIBLE } diff --git a/common/src/main/java/com/habitrpg/common/habitica/views/ValueBar.kt b/common/src/main/java/com/habitrpg/common/habitica/views/ValueBar.kt index 0ceeeef42..fda887a2f 100644 --- a/common/src/main/java/com/habitrpg/common/habitica/views/ValueBar.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/views/ValueBar.kt @@ -84,7 +84,7 @@ class ValueBar(context: Context, attrs: AttributeSet?) : FrameLayout(context, at private fun updateBar() { binding.progressBar.set(currentValue, maxValue) binding.progressBar.pendingValue = pendingValue - setValueText(formatter.format(currentValue) + " / " + formatter.format(maxValue.toInt()) + " " + valueSuffix) + setValueText(formatter.format(currentValue) + " / " + formatter.format(maxValue.toInt()) + " " + (valueSuffix ?: "")) } init { diff --git a/version.properties b/version.properties index 406f1a950..98dc2e560 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ NAME=4.3 -CODE=6471 \ No newline at end of file +CODE=6491 \ No newline at end of file