From 387ac4e5263df33c786d2b5f80cabba81fd5c07b Mon Sep 17 00:00:00 2001 From: easyhooon Date: Wed, 6 Aug 2025 21:18:09 +0900 Subject: [PATCH 01/13] =?UTF-8?q?[BOOK-232]=20feat:=20=EC=8A=A4=ED=94=8C?= =?UTF-8?q?=EB=9E=98=EC=8B=9C=20=ED=99=94=EB=A9=B4=20Ui=20=EA=B5=AC?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 2 +- core/designsystem/build.gradle.kts | 2 + .../src/main/res/drawable/ic_dummy_splash.xml | 11 ++++ .../src/main/res/values/colors.xml | 1 + .../src/main/res/values/splash.xml | 10 +++ .../feature/main/splash/SplashPresenter.kt | 15 ++++- .../booket/feature/main/splash/SplashUi.kt | 61 +++++++++++++++++- .../src/main/res/drawable/ic_reed_logo.png | Bin 0 -> 7415 bytes feature/main/src/main/res/values/strings.xml | 1 + 9 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 core/designsystem/src/main/res/drawable/ic_dummy_splash.xml create mode 100644 core/designsystem/src/main/res/values/splash.xml create mode 100644 feature/main/src/main/res/drawable/ic_reed_logo.png diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1443cd8d..2533709a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,7 +19,7 @@ android:networkSecurityConfig="@xml/network_security_config" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/Theme.Booket" + android:theme="@style/Theme.Booket.Splash" tools:targetApi="31"> + + + + diff --git a/core/designsystem/src/main/res/values/colors.xml b/core/designsystem/src/main/res/values/colors.xml index ca1931bc..2fe46cd5 100644 --- a/core/designsystem/src/main/res/values/colors.xml +++ b/core/designsystem/src/main/res/values/colors.xml @@ -7,4 +7,5 @@ #FF018786 #FF000000 #FFFFFFFF + #FF2F9647 diff --git a/core/designsystem/src/main/res/values/splash.xml b/core/designsystem/src/main/res/values/splash.xml new file mode 100644 index 00000000..83ffcd93 --- /dev/null +++ b/core/designsystem/src/main/res/values/splash.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt index 1e1c200c..f956a7a1 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt +++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt @@ -1,7 +1,10 @@ package com.ninecraft.booket.feature.main.splash import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue import com.ninecraft.booket.core.data.api.repository.AuthRepository import com.ninecraft.booket.core.data.api.repository.UserRepository import com.ninecraft.booket.core.model.AutoLoginState @@ -13,12 +16,14 @@ import com.ninecraft.booket.feature.screens.SplashScreen import com.skydoves.compose.effects.RememberedEffect import com.slack.circuit.codegen.annotations.CircuitInject import com.slack.circuit.retained.collectAsRetainedState +import com.slack.circuit.retained.rememberRetained import com.slack.circuit.runtime.Navigator import com.slack.circuit.runtime.presenter.Presenter import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import dagger.hilt.android.components.ActivityRetainedComponent +import kotlinx.coroutines.delay class SplashPresenter @AssistedInject constructor( @Assisted private val navigator: Navigator, @@ -30,8 +35,16 @@ class SplashPresenter @AssistedInject constructor( override fun present(): SplashUiState { val onboardingState by userRepository.onboardingState.collectAsRetainedState(initial = OnboardingState.IDLE) val autoLoginState by authRepository.autoLoginState.collectAsRetainedState(initial = AutoLoginState.IDLE) + var isSplashTimeCompleted by rememberRetained { mutableStateOf(false) } + + LaunchedEffect(Unit) { + delay(3000L) + isSplashTimeCompleted = true + } + + RememberedEffect(onboardingState, autoLoginState, isSplashTimeCompleted) { + if (!isSplashTimeCompleted) return@RememberedEffect - RememberedEffect(onboardingState, autoLoginState) { when (onboardingState) { OnboardingState.NOT_COMPLETED -> { navigator.resetRoot(OnboardingScreen) diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt index fd485ee0..3fb5b29c 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt +++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt @@ -1,17 +1,76 @@ package com.ninecraft.booket.feature.main.splash +import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.ninecraft.booket.core.designsystem.DevicePreview +import com.ninecraft.booket.core.designsystem.theme.Green500 +import com.ninecraft.booket.core.designsystem.theme.ReedTheme +import com.ninecraft.booket.feature.main.R import com.ninecraft.booket.feature.screens.SplashScreen import com.slack.circuit.codegen.annotations.CircuitInject import dagger.hilt.android.components.ActivityRetainedComponent +import tech.thdev.compose.exteions.system.ui.controller.rememberSystemUiController @CircuitInject(SplashScreen::class, ActivityRetainedComponent::class) @Composable fun SplashUi( modifier: Modifier = Modifier, ) { - Box(modifier = modifier.fillMaxSize()) + val systemUiController = rememberSystemUiController() + + DisposableEffect(systemUiController) { + systemUiController.setSystemBarsColor( + color = Green500, + darkIcons = false, + ) + + onDispose {} + } + + Box( + modifier = modifier + .fillMaxSize() + .background(ReedTheme.colors.bgPrimary), + contentAlignment = Alignment.Center, + ) { + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Image( + painter = painterResource(R.drawable.ic_reed_logo), + contentDescription = "Reed Logo", + modifier = Modifier.width(182.dp), + ) + Spacer(modifier.height(ReedTheme.spacing.spacing5)) + Text( + text = stringResource(R.string.splash_title), + color = ReedTheme.colors.contentInverse, + style = ReedTheme.typography.heading2SemiBold, + ) + } + } +} + +@DevicePreview +@Composable +private fun SplashPreview() { + ReedTheme { + SplashUi() + } } diff --git a/feature/main/src/main/res/drawable/ic_reed_logo.png b/feature/main/src/main/res/drawable/ic_reed_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1cf1d821196e2f5e66f50aad4c38478caaaba17d GIT binary patch literal 7415 zcmX9@1zc0#7pH`ckkK8ZL^=fqf{f7uA|WX)C6dyJz#LN=1%9-2cSs{$$|$8vhQtVA zv>^Y%|9w8&d-vXR&;8yw@0{;>@1N+ZQ;;%~;^E;@XllTo;^7g1anHj5V%)zsS^Pfk z2K3M{^~S>k%ijF(Rg=Z7ah3SqPt~D#m7}a%xB`)*vW_wyUQHa?rOh2YJl1GUn6jZi z{_Y~?_0-@b@t=YH+5J#=A}K07Do(DqG1ifQw*W?UJeV~NJ_vsfS8(DoaVNt1n(_)o zi%vv~7!_>z#m3r9x2~kJA5Z>Zz=z>3GFbvDDyng~Z|h>up=zaJWza<&jS2u)7gGw4 zEe#H^5IGlEU1PkFHQ?`BYqF>sId+()LE^3xqgt52v~%;nMG7J=F0R}h$f}(?C+>;a zcKUHEd1bH|9E8*Ty#8W5=sU@+Qnqq?1VbxTDF-fA=<~? z3=U;1*WbmiTTV0n!?P1N#BB z5D4l5L18f3Wjn^+TOeVk3u*JWkog-))oxMt8F%sDDxG2f%3paiOVXFmzVhFK4WGa& zf3v++h5?iRC6s!fs5mKoeRjFIxyg!K1*}*rJ4_6|qj_riY+cJ~$zC&k;NtK6Kl$@S z`ROlSAxTmA?~q8f7cJCYm~KP1?_W}Us!u%vPJ&xjl}6SRM~{>&eCxpwlT7oEMWEq> zFTk}CCxRiR_0kd76FQv!pxQQmqf2ryvuwV1l77fLzL(MG)hs~pM9CW{jh2gS&gz=< z?`7A_5u+4Ld(m_h5}Ew$LZl=-IE-XseDC*hyG4fg$Mc52)X>^-@N za+F_7USRt;+;D$-!*a6gl{M_Vl{E#UbH464Bj+rV6VQ%sNSrRm8N&GY$5kX$#*LeW zUYTY9?$(jRAKEiUIY4(H4&St7yQG?l{5_skiD;g0<(H|VV?^;c2Y;D5x~@f4CMVU` z|Fw_L5xpdTXtI#PV)%n?;t<#*dAjom??7t`HlDgyNU;gy>efRLY zN)gl!%i2_$1u*A(=?DQWd#BU;Khq1-nM^K7PT)1@Pc$(I|b`3B5Fz~-%yw$za z-6de-Wt-=U*NChlnm!D)R z)E}PeY-$i5X&BFSCoX-;=@qNv=b@cs`6Pd!TjWu!!Gp-j6#+tUv#3#ZRX_RZr^A*u zVXNm~W#hoGopx6>mX~n1raYr}7bd3nJTs$z|Mu+O9+W+*N1zmkb2XT%n0Q~DX?0P9Z zP8KBpL6etNG11d`;GVvoa|GXtqKY*{HZhE9U*~&bgaLWV3hWce%TAidnhrK4`&COj zLz^)uC)IS$bFh2AeRMx(i8?Ja3`|(L=a0@kvvNBDaJ?#3*M}ngAO6V>IzEo?sWthP zVF{HCjH&0pU|_Dzzn}_)zxrm3N&#Ty_UiMhvy%wPDY(eNWM>u3)b*r?>_OJ=z4d|L zKb(40g*cjthW+Nt+1G|^nHLcxK9ZRwFMcZy7ea4q?6~(z`aeW2<(vGnSW4G$I6ABw z+|Zt*D{~pqbP{j_c8I?{s@n~qv;mk7F1rOhRd=GZm1BX>O#(TEJm;!oKrpGd8DaRn z;qXGPUx$*F2EA=c$6t2!joL}><-UtQ5nt)PoFqIIa}p?|c|<)(J*^D8-gD&C7Acf$ zyF=xsox#Pv_g!T0eakp*vZa~(#5IEk-k6T%Z+Ny@Bb>Q(@xp^#&y-n?P4UD1$g0sS&mA)vSB*Mv@_***@^i zGkHm1qXm3h9coZ1bDFhf^IpN=g@WkowEC!4J141oA!VEv==Hgh)daz!li zx3xC)nEl9DIWIddO6L*Pbv|Bv(#)%*F%kA_OG!eWIMb=Age`!Q2h9 z9g#!aiHG~oCpe$qRq++|h%{2rHlFp*PKzs>P6PMGT2!hNq6k-|9$Q5DFfzaV^11j$ zRc#HaL@Q~m7UEqH5G(rN1s(iVFQ~SyijnaVtyQ32Nfr6=29xjE`;7h*w#B*JIm)Z!^Q6$w@@YaTndV|w zM)XF9)!dLApYhxezurADwDh;L21`p`H-Vf0+6$H5kcVh}P)$J|yBX4qt~+_{ z)H;DOe^;oZ3URTxD;}hT9$HY@n&qKGzUtB%yc``qc3DoSVE^8s%F3j3@4)xlct@jS zK!w1WOu&uh=Bs)C@`y?BA<+DEXZ3YJNR~C%`f(x&`>RJjWR<{Fy_grf16V==4QK{s zLmM%5f4=u(>|&SJMxM-!dQ->Fo~AiPDy&*SBj&gFiT#d#NBMl>0KZ1MaA(M!>s^;x zNnRi2*ZIR#I&iRkpmcxh{o#+)G?yPIn&5Fm(+!`L)?AAw|LpX^a9GJ)^ECE!6eHwEQY&6`?)hq%Ue?3B{|yp)y|n_bXT27%~Y8@*{}&^ z_nVCFc#z-5ZnYBRsNdQb^7Bbh(ku65RMEirwdQi9!%0qd&AthVbLjQvbc@Btbb~5I zpk`I6MO>G`dr>hsYoXiQpo%t*?(=SC8vOhM86sy4yE{SXZe7_n1YZ%$N1!osfRS@) zq7bugiE7i`_gJyL7-jC{pWF$04`JiR)=y}-MBmE;veY&{`W=2PMDaxHtLSSg^e6oM z@O?EGzPEsoD)jw6rhjc;{S{KaNs`|INhed4m$e9>{lO6ZJT z(%L*dm9;r#7}fsG^fyyNA?k2WD~Llv{pL+Z!>Tm(w`w z8Ll6n^3YP5B38^arQn2?O0FL#rH`{ zdnbEBJ}LSIsn4NSWuvpR{8P`AFvo6E55MRT)QSNj!jh0V(dA5{U+Tkj2_vx4u^P2j z|BW~j8`#;R8}nlNN4dceq~e}YNi>}`pazAxEZrL4rdt{XX+o0fQ$~lfm+WO{@0PhO z&;MK$-;<7`>XCo=+$O=<-%W`c_N}}iom2&B6RXGeO;@dq!6$!hcdSHZPW4Xqk{oFx zwDjc*`q2}Qu~cy8vER}V-Zn4&Paqdlm^ggKxa(eAq>S6@2$)+p&Om(j@FEwp$$!BX zJZl}QPcTTY=EOqEhGS7Lv9fe)rKA%R`UCtM?%(XI^vnLq&|MzRwA}-jjEI{ zjmg1kTircGp)Rro97p6zC-+02{n_|f*TDHKfb_`#iBRAPgl#fw^JR-|0miUf*w6t` zQx>k&fE|UxI2r<3D_Y9K>!lVDS&8E-wWqm1-+A6!4rhe!9L|{fhn6=NuMYHpF;Le1 z=N@d(PerJHLY!0oSat`+?Bq&>d%dO%jOHS|@2Xd*%)K9Z;L!ef$$&yhfPCY%K);D?1dVLZLLlE?;$0k|k8Zj(I=j{lS<5=NE?7 zihr^E`ZIMv(R|*z!w-6E>@9K07)W{8#NLZN^8C*Qpn}xN_+V;`;82;<3Rg<-CG;o# zqOz~Nv}Y=Ul5|lmMZiNpR2s0Wmv2B~Xv2!60VOCIIm=H1`#lF>_4h1T(MyexPW@#L z_kDeeYn~}%k64_SAqv%1){fVO9Gk?g)wJ-j&HIf}Pr#O4RpFVzwPhR98EZb#I#gL* zkFav=TR})OmC~A}xu4Ctj!lJ_XcyT5knQ8o_bJj)JqaC=#Yub@&&hIknyB|e=@FnH zY9vCFJA`svkB}G^(uw-O>^XHaW)@Md&Bdpl{V=EhIwpmH9aG4jt3C1m%b#1t?Q3!} z^BrGyDDI-7^YZe<<~v?nA~D&K;9hnS&itGSjb)XoAE(dJTUm5l3#rMN2ree*j?HWa z!q%gJH^3!S2}CIfmJ;ygmzt_@L&#S;>6L7p)=<}$lMmpi`Y&zHwAdn0BGrvhDGmuW zvY)|IM?*~^i(T@7<%X!X#Fkl#K5X8ruF8|QU$6z#+zWHE0K#~>-+_`=X>SPiZr^|AEI9Gprx9E>CKgEC)Gtadn++cppw zZS)s!8Q)gRDH6B@e9Vav>hzKc#={7Ww!tyt+y-laI0Cm?Ae{k&;|E|ycl8ac zK9DVCksWf71`+STE87pUMTK%QQ*q3x9vMItfU#HjwR}C<7L})*Blh*%ZcAr&%^hLM zhYcI24rf~cnqL6`+%oJO$g+JLaS9@<{bmO^H=O&yGzif47?gTz$mnTDj{wh>TYjILa1ebu|d(oaD*ErL<*TaEpV0`5) zuvGem?pN^&s|r%w;jV?^*plMZKv^;XAx+Dg-E9A=V7H=OZ44 z3r@3@(ca7++1;I;RCqW85z3sTHL=MnX)@1X=3Frbyao62#esPy6kHA2=ac@v^AkLv zybK^N8gBQE;G9e%2NQ4IWzroQn{hc?Ys@oYio-yk%d*S1tKqiL*VA4(PhizJykcN? znQjnLwK3KPmrN+-3$Cn4cV zqK^vY7QvH{cQoU-o%jbZP-wx?TZ`oHOs^~l|7g zN4c<}a3}|`(wqo)4wr+@(9J!6p5CF7Mqrzao@q$;E+%W`Z0P%+Keo4Yf*`SdB^8F1 zDC2Ns*7gPcjoaApOo{fGwb_hZ`o0{Ly#=&9+QHTQX)1WCfv5Q=r~hADV;L?bC|Zyy zY)0`z$?9jpJH_|7a8-7|K;lSWo`i|Y{Mz65<2k5#TzbcJ zzY9HWpLl@9?;^yds18=yE+u3J0?E$D?w!?~8fIcW{*LwF@PUKLtXy_buInd!^M~xC zzLX!G<ECU`p9(QAP(CfM zL@$9IM&bCs@7@?Q4VeY{GaO6MBj;|YoYb&*1 z5a#>q*ouY{CbscFa?XJKo)(whBo8Jvw5#-yW*f7@oPil{a0b^3*gk}

xce%_0Ld z+cU&obd~ySi8~-v;EazgyG9AZPezW_%))Gv@u%}Ji>r{N8L^)E3l^xAQ?ULsw=o~)BJaoJPUi+{msF*ic6vGf+1r@8*oW?+G{R+_Q|Fh$ z!6fl@2_!^ivx~}+Hh_bBPb0xMe4fPev-Dg{+oUE8$YHxPn!8wO&K(Q4+SpZROK|<1 zG#m+!yH>k4Hht$l!gAe}~ca(LW^A}o+<*!h{`pHrVjmHOTLR_7aA!_%95z{cGAlF*uNx1uQyhC&FfllUqKD0OVO z&}gAolck$SQ3b@j_LbWG*Bdb-j$eUn;dQ)n!ay ze5j}@V+-)ql8<(ZGTaJelH7eT=KM{5dgTego5&oB+sN0EcA{3O=qMV`5@Twsh_qxFajU=inG&U^LgY}PzRXuCJ zIvq1GzvYupfzuz@|2|f=lrS0oTw>quCd3Ml-nha0r<@}{9GHpdB0&Ay2hq+%tqG zp@Dck@h&{+0gH<)DW|X{Szq3r3;AX{HUOm{ce;-_W5i&sS2Me*6&yk&=*HJ3xZjgl zl*0}ql#3W#Tsk#D4uhb+Tl`y8O%fqMue=ai8}?Iyiuy$o!o7w3o`8ZV18@TM6 z01ZxaMlp0I=NApW6)5^Harl_tGe``xlwr(^Pus83(VyxqHPdYy+>{*GTSVEOqPGWL z8@Id>UaM|UTwqh_a4rHHQTZ}oO*N5oNN<{Dx}-;MN^XicI&}|V8{Wm085@?c*;P=g z0QxvNg4w!;BRh#LjUraaDu6{z zh)G4X24_NoMt|TC#V>Ml4w7++zow39h5aoJu8MoE>YtRS6C=J8=W64J>gNILLn}SM4}dG-Gvrn+Io?s8%`Pgq z)Cn#YH0lUeBfqCExST4MGV$u^`O_qf`xW#1ZzFF6o_!w^7j5TwC^$Xo#oG&JgUwft zGD7+d=A!EvnkgSfSW5G~*+0&@WYfi2os$*|M2!Z9=KJ&6f^t<`UgE0Ag2R;hOAd`s z_V%>hS>m{lf*1eFGvYXBCRWCwzrvF<92<<^HbZ8-K!5x6Ph~ECt9p!5UK~PlVBLdu zS1tvF2`35TM0c4|f0DB)e)8qrEpDHyb}g`UklNiMNqc0DeO{lT%bB3Prwqgvj~r7- z-l0UrK9b_5;BzD4>U{Iril)C)+1?_#^Llc5^<=VMzX%&y zNnnzFiCG90uxLzBfxeulM_*kRTAA)LuUzB1FJBxLus5>fzEk39s_Mcjq1NI51BuxY AX#fBK literal 0 HcmV?d00001 diff --git a/feature/main/src/main/res/values/strings.xml b/feature/main/src/main/res/values/strings.xml index e3d059c3..2ae49c00 100644 --- a/feature/main/src/main/res/values/strings.xml +++ b/feature/main/src/main/res/values/strings.xml @@ -2,4 +2,5 @@ 도서 검색 내 서재 + 책 덮기 전 한 문장을 기록해보세요 From c30c03f2eadc49211795e7e7804c9c4e7a1a8ace Mon Sep 17 00:00:00 2001 From: easyhooon Date: Wed, 6 Aug 2025 21:18:57 +0900 Subject: [PATCH 02/13] =?UTF-8?q?[BOOK-232]=20chore:=20systemUiController?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=20=EC=86=8D=EC=84=B1=20=EC=A0=81=EC=9A=A9?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit isDarkTheme() 분기 처리 제거 isNavigationBarContrastEnforced default 값 적용 --- .../main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt | 6 ++++++ .../com/ninecraft/booket/feature/main/MainActivity.kt | 5 +---- .../kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt | 5 ++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt index ef0b1de6..52077e11 100644 --- a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt +++ b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt @@ -51,6 +51,12 @@ internal fun HomeUi( color = HomeBg, darkIcons = true, ) + + systemUiController.setSystemBarsColor( + color = White, + darkIcons = true, + ) + onDispose { systemUiController.setStatusBarColor( color = White, diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt index be75843e..308a9c13 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt +++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt @@ -4,7 +4,6 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier @@ -33,13 +32,11 @@ class MainActivity : ComponentActivity() { setContent { val systemUiController = rememberSystemUiController() - val isDarkTheme = isSystemInDarkTheme() DisposableEffect(systemUiController) { systemUiController.setSystemBarsColor( color = White, - darkIcons = !isDarkTheme, - isNavigationBarContrastEnforced = false, + darkIcons = true, ) onDispose {} diff --git a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt index 7ab7e7e5..e993fd09 100644 --- a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt +++ b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt @@ -144,13 +144,12 @@ private fun CameraPreview( DisposableEffect(systemUiController) { systemUiController.setSystemBarsColor( color = Neutral950, - isNavigationBarContrastEnforced = false, + darkIcons = false ) onDispose { systemUiController.setSystemBarsColor( color = White, - darkIcons = !isDarkTheme, - isNavigationBarContrastEnforced = false, + darkIcons = true, ) } } From c3670fdd0e2dbb8db21abfb2a06fb36711146f2f Mon Sep 17 00:00:00 2001 From: easyhooon Date: Wed, 6 Aug 2025 21:20:53 +0900 Subject: [PATCH 03/13] [BOOK-232] chore: code style check success --- .../booket/feature/record/ocr/OcrUi.kt | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt index e993fd09..bc69f516 100644 --- a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt +++ b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt @@ -12,7 +12,6 @@ import androidx.camera.core.ImageAnalysis import androidx.camera.view.LifecycleCameraController import androidx.camera.view.PreviewView import androidx.compose.foundation.background -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -118,7 +117,19 @@ private fun CameraPreview( } val systemUiController = rememberSystemUiController() - val isDarkTheme = isSystemInDarkTheme() + + DisposableEffect(systemUiController) { + systemUiController.setSystemBarsColor( + color = Neutral950, + darkIcons = false, + ) + onDispose { + systemUiController.setSystemBarsColor( + color = White, + darkIcons = true, + ) + } + } LaunchedEffect(Unit) { val granted = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED @@ -141,19 +152,6 @@ private fun CameraPreview( } } - DisposableEffect(systemUiController) { - systemUiController.setSystemBarsColor( - color = Neutral950, - darkIcons = false - ) - onDispose { - systemUiController.setSystemBarsColor( - color = White, - darkIcons = true, - ) - } - } - Box( modifier = modifier.fillMaxSize(), ) { From 6b2de610047254e173b451b8a1cfebaffd8538ee Mon Sep 17 00:00:00 2001 From: easyhooon Date: Wed, 6 Aug 2025 21:22:49 +0900 Subject: [PATCH 04/13] =?UTF-8?q?[BOOK-232]=20chore:=20SplashUi=20?= =?UTF-8?q?=EB=88=84=EB=9D=BD=EB=90=9C=20Spacer=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt index 3fb5b29c..09bb30ca 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt +++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt @@ -63,6 +63,7 @@ fun SplashUi( color = ReedTheme.colors.contentInverse, style = ReedTheme.typography.heading2SemiBold, ) + Spacer(modifier.height(ReedTheme.spacing.spacing8)) } } } From 036810826ee6c7af293741cd784582b8a48124fb Mon Sep 17 00:00:00 2001 From: easyhooon Date: Wed, 6 Aug 2025 21:44:33 +0900 Subject: [PATCH 05/13] =?UTF-8?q?[BOOK-232]=20fix:=20ActionBar=EA=B0=80=20?= =?UTF-8?q?=EB=85=B8=EC=B6=9C=EB=90=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://stackoverflow.com/questions/71584663/splash-screen-api-is-showing-action-bar-for-android-12 --- app/src/main/AndroidManifest.xml | 2 +- feature/main/src/main/AndroidManifest.xml | 2 +- .../kotlin/com/ninecraft/booket/feature/main/MainActivity.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2533709a..1443cd8d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,7 +19,7 @@ android:networkSecurityConfig="@xml/network_security_config" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/Theme.Booket.Splash" + android:theme="@style/Theme.Booket" tools:targetApi="31"> + android:theme="@style/Theme.Booket.Splash"> diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt index 308a9c13..489fcc7d 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt +++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt @@ -26,8 +26,8 @@ class MainActivity : ComponentActivity() { lateinit var circuit: Circuit override fun onCreate(savedInstanceState: Bundle?) { - enableEdgeToEdge() installSplashScreen() + enableEdgeToEdge() super.onCreate(savedInstanceState) setContent { From 775ec6ef588c4d819c5bd071757018b20a0c8240 Mon Sep 17 00:00:00 2001 From: easyhooon Date: Wed, 6 Aug 2025 21:53:55 +0900 Subject: [PATCH 06/13] =?UTF-8?q?[BOOK-232]=20chore:=20=ED=86=A0=EB=81=BC?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/designsystem/src/main/res/drawable/ic_dummy_splash.xml | 2 +- .../com/ninecraft/booket/feature/main/splash/SplashUi.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/designsystem/src/main/res/drawable/ic_dummy_splash.xml b/core/designsystem/src/main/res/drawable/ic_dummy_splash.xml index 34f95de5..b96b4a50 100644 --- a/core/designsystem/src/main/res/drawable/ic_dummy_splash.xml +++ b/core/designsystem/src/main/res/drawable/ic_dummy_splash.xml @@ -6,6 +6,6 @@ + android:pathData="M0,0h192v192h-192z" /> diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt index 09bb30ca..106a8341 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt +++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt @@ -57,13 +57,13 @@ fun SplashUi( contentDescription = "Reed Logo", modifier = Modifier.width(182.dp), ) - Spacer(modifier.height(ReedTheme.spacing.spacing5)) + Spacer(Modifier.height(ReedTheme.spacing.spacing5)) Text( text = stringResource(R.string.splash_title), color = ReedTheme.colors.contentInverse, style = ReedTheme.typography.heading2SemiBold, ) - Spacer(modifier.height(ReedTheme.spacing.spacing8)) + Spacer(Modifier.height(ReedTheme.spacing.spacing8)) } } } From 20e266ae7b16e327c70dde8bf9cc5c51229c1565 Mon Sep 17 00:00:00 2001 From: easyhooon Date: Wed, 6 Aug 2025 22:04:53 +0900 Subject: [PATCH 07/13] [BOOK-232] chore: run build success MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 완료된 TODO 제거 --- .../com/ninecraft/booket/feature/home/HomeUi.kt | 1 - .../ninecraft/booket/feature/library/LibraryUi.kt | 1 - .../ninecraft/booket/feature/record/ocr/OcrUi.kt | 14 -------------- 3 files changed, 16 deletions(-) diff --git a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt index c499d821..071446e6 100644 --- a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt +++ b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt @@ -42,7 +42,6 @@ internal fun HomeUi( state: HomeUiState, modifier: Modifier = Modifier, ) { - // TODO: Android 15에서 statusBar 색상 적용 안되는 문제 있음. 해결 예정. val systemUiController = rememberSystemUiController() DisposableEffect(systemUiController) { diff --git a/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUi.kt b/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUi.kt index 00a31f8a..38722a33 100644 --- a/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUi.kt +++ b/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUi.kt @@ -42,7 +42,6 @@ internal fun LibraryUi( state: LibraryUiState, modifier: Modifier = Modifier, ) { - // TODO: Android 15에서 statusBar 색상 적용 안되는 문제 있음. 해결 예정. val systemUiController = rememberSystemUiController() DisposableEffect(systemUiController) { diff --git a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt index 2797ddd2..626298e6 100644 --- a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt +++ b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt @@ -139,20 +139,6 @@ private fun CameraPreview( } } - DisposableEffect(systemUiController) { - systemUiController.setSystemBarsColor( - color = Neutral950, - isNavigationBarContrastEnforced = false, - ) - onDispose { - systemUiController.setSystemBarsColor( - color = White, - darkIcons = !isDarkTheme, - isNavigationBarContrastEnforced = false, - ) - } - } - LaunchedEffect(Unit) { val granted = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED if (granted) { From 7caa5e0262ed9631afeda3115a138b0bac6e6b00 Mon Sep 17 00:00:00 2001 From: easyhooon Date: Wed, 6 Aug 2025 23:14:41 +0900 Subject: [PATCH 08/13] =?UTF-8?q?[BOOK-232]=20chore:=20SplashUi=20?= =?UTF-8?q?=EB=82=B4=20onDispose=20{}=20=EB=82=B4=20SystemBar=20=EC=BB=AC?= =?UTF-8?q?=EB=9F=AC=20=EC=9B=90=EB=B3=B5=20=EC=BD=94=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ninecraft/booket/feature/main/splash/SplashUi.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt index 106a8341..f86a622c 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt +++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.unit.dp import com.ninecraft.booket.core.designsystem.DevicePreview import com.ninecraft.booket.core.designsystem.theme.Green500 import com.ninecraft.booket.core.designsystem.theme.ReedTheme +import com.ninecraft.booket.core.designsystem.theme.White import com.ninecraft.booket.feature.main.R import com.ninecraft.booket.feature.screens.SplashScreen import com.slack.circuit.codegen.annotations.CircuitInject @@ -39,7 +40,12 @@ fun SplashUi( darkIcons = false, ) - onDispose {} + onDispose { + systemUiController.setSystemBarsColor( + color = White, + darkIcons = true, + ) + } } Box( From 6086beae7f7d155e043ef479b0061c84ad6b1bf1 Mon Sep 17 00:00:00 2001 From: easyhooon Date: Wed, 6 Aug 2025 23:14:53 +0900 Subject: [PATCH 09/13] =?UTF-8?q?[BOOK-232]=20chore:=20API=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ninecraft/booket/core/network/service/ReedService.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/network/src/main/kotlin/com/ninecraft/booket/core/network/service/ReedService.kt b/core/network/src/main/kotlin/com/ninecraft/booket/core/network/service/ReedService.kt index 1f45b52b..2f0a1314 100644 --- a/core/network/src/main/kotlin/com/ninecraft/booket/core/network/service/ReedService.kt +++ b/core/network/src/main/kotlin/com/ninecraft/booket/core/network/service/ReedService.kt @@ -35,10 +35,11 @@ interface ReedService { @POST("api/v1/auth/signout") suspend fun logout() - @PUT("api/v1/auth/terms-agreement") + // User endpoints (auth required) + @PUT("api/v1/users/terms-agreement") suspend fun agreeTerms(@Body termsAgreementRequest: TermsAgreementRequest): TermsAgreementResponse - @GET("api/v1/auth/me") + @GET("api/v1/users/me") suspend fun getUserProfile(): UserProfileResponse // Book endpoints (auth required) From b4e0500a6398e1e04e17de6b2c8aab75289f5a42 Mon Sep 17 00:00:00 2001 From: easyhooon Date: Wed, 6 Aug 2025 23:25:56 +0900 Subject: [PATCH 10/13] =?UTF-8?q?[BOOK-232]=20chore:=20HomeUi=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=20=EC=97=86=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt index 071446e6..b0beabc2 100644 --- a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt +++ b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt @@ -50,11 +50,6 @@ internal fun HomeUi( darkIcons = true, ) - systemUiController.setSystemBarsColor( - color = White, - darkIcons = true, - ) - onDispose { systemUiController.setStatusBarColor( color = White, From 09376e02e41a9ac860b4304d1eb58afd8033cc90 Mon Sep 17 00:00:00 2001 From: easyhooon Date: Thu, 7 Aug 2025 06:46:12 +0900 Subject: [PATCH 11/13] =?UTF-8?q?[BOOK-232]=20refactor:=20DelegateNavigato?= =?UTF-8?q?r=20->=20=EB=AA=A8=EB=93=A0=20=ED=99=94=EB=A9=B4=20Scaffold=20m?= =?UTF-8?q?igration=20WIP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/detail/book/BookDetailUi.kt | 26 +- .../feature/detail/record/RecordDetailUi.kt | 40 ++- .../booket/feature/home/HomePresenter.kt | 8 + .../ninecraft/booket/feature/home/HomeUi.kt | 75 +++-- .../booket/feature/home/HomeUiState.kt | 2 + .../feature/library/LibraryPresenter.kt | 8 + .../booket/feature/library/LibraryUi.kt | 66 ++-- .../booket/feature/library/LibraryUiState.kt | 2 + .../booket/feature/login/LoginPresenter.kt | 4 +- .../ninecraft/booket/feature/login/LoginUi.kt | 24 +- .../termsagreement/TermsAgreementPresenter.kt | 4 +- .../termsagreement/TermsAgreementUi.kt | 175 +++++------ .../booket/feature/main/MainActivity.kt | 5 +- .../BottomNavigationPresenter.kt | 56 ---- .../bottomnavigation/BottomNavigationUi.kt | 45 --- .../BottomNavigationUiState.kt | 17 -- .../bottomnavigation/DelegateNavigator.kt | 48 --- .../feature/main/splash/SplashPresenter.kt | 6 +- .../booket/feature/main/splash/SplashUi.kt | 9 +- .../booket/feature/onboarding/OnboardingUi.kt | 12 +- .../booket/feature/record/ocr/OcrUi.kt | 287 +++++++++--------- .../record/register/RecordRegisterUi.kt | 85 +++--- feature/screens/build.gradle.kts | 11 +- .../booket/feature/screens/Screens.kt | 3 - .../screens}/component/MainBottomBar.kt | 5 +- .../feature/screens}/component/MainTab.kt | 4 +- .../Navigator.kt} | 3 +- .../screens/src/main/res/drawable/ic_home.xml | 9 + .../src/main/res/drawable/ic_library.xml | 9 + .../main/res/drawable/ic_selected_home.xml | 9 + .../main/res/drawable/ic_selected_library.xml | 9 + .../screens/src/main/res/values/strings.xml | 4 + .../feature/search/book/BookSearchUi.kt | 32 +- .../feature/search/library/LibrarySearchUi.kt | 28 +- .../booket/feature/settings/SettingsUi.kt | 241 ++++++++------- .../settings/osslicenses/OssLicensesUi.kt | 44 +-- .../booket/feature/webview/WebViewUi.kt | 33 +- 37 files changed, 707 insertions(+), 741 deletions(-) delete mode 100644 feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationPresenter.kt delete mode 100644 feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUi.kt delete mode 100644 feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUiState.kt delete mode 100644 feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/DelegateNavigator.kt rename feature/{main/src/main/kotlin/com/ninecraft/booket/feature/main => screens/src/main/kotlin/com/ninecraft/booket/feature/screens}/component/MainBottomBar.kt (97%) rename feature/{main/src/main/kotlin/com/ninecraft/booket/feature/main => screens/src/main/kotlin/com/ninecraft/booket/feature/screens}/component/MainTab.kt (90%) rename feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/{extensions.kt => extensions/Navigator.kt} (72%) create mode 100644 feature/screens/src/main/res/drawable/ic_home.xml create mode 100644 feature/screens/src/main/res/drawable/ic_library.xml create mode 100644 feature/screens/src/main/res/drawable/ic_selected_home.xml create mode 100644 feature/screens/src/main/res/drawable/ic_selected_library.xml create mode 100644 feature/screens/src/main/res/values/strings.xml diff --git a/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt b/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt index 8747c4ea..861b6f47 100644 --- a/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt +++ b/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt @@ -1,6 +1,7 @@ package com.ninecraft.booket.feature.detail.book import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -36,8 +37,8 @@ import com.ninecraft.booket.core.designsystem.component.button.ReedButton import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorStyle import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle import com.ninecraft.booket.core.designsystem.theme.ReedTheme +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar -import com.ninecraft.booket.core.ui.component.ReedFullScreen import com.ninecraft.booket.feature.detail.book.component.BookUpdateBottomSheet import com.ninecraft.booket.feature.detail.book.component.CollectedSeed import com.ninecraft.booket.feature.detail.book.component.RecordSortBottomSheet @@ -65,14 +66,21 @@ internal fun BookDetailUi( eventSink = state.eventSink, ) - ReedFullScreen(modifier = modifier) { - ReedBackTopAppBar( - title = "", - onBackClick = { - state.eventSink(BookDetailUiEvent.OnBackClick) - }, + ReedScaffold( + modifier = modifier.fillMaxSize(), + topBar = { + ReedBackTopAppBar( + title = "", + onBackClick = { + state.eventSink(BookDetailUiEvent.OnBackClick) + }, + ) + }, + ) { innerPadding -> + BookDetailContent( + state = state, + innerPadding = innerPadding, ) - BookDetailContent(state = state) } if (state.isBookUpdateBottomSheetVisible) { @@ -122,11 +130,13 @@ internal fun BookDetailUi( @Composable internal fun BookDetailContent( state: BookDetailUiState, + innerPadding: PaddingValues, modifier: Modifier = Modifier, ) { Column( modifier = modifier .fillMaxSize() + .padding(innerPadding) .verticalScroll(rememberScrollState()), ) { Row( diff --git a/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt b/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt index d254d1e0..9635444b 100644 --- a/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt +++ b/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt @@ -1,8 +1,8 @@ package com.ninecraft.booket.feature.detail.record -import androidx.compose.foundation.background import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -28,7 +28,7 @@ import com.ninecraft.booket.core.designsystem.component.ReedDivider import com.ninecraft.booket.core.designsystem.theme.ReedTheme import com.ninecraft.booket.core.designsystem.theme.White import com.ninecraft.booket.core.model.RecordDetailModel -import com.ninecraft.booket.core.ui.component.ReedFullScreen +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.core.ui.component.ReedTopAppBar import com.ninecraft.booket.feature.detail.R import com.ninecraft.booket.feature.detail.record.component.QuoteBox @@ -48,25 +48,37 @@ internal fun RecordDetailUi( state = state, ) - ReedFullScreen(modifier = modifier) { - ReedTopAppBar( - title = stringResource(R.string.review_detail_title), - startIconRes = designR.drawable.ic_close, - startIconDescription = "Close Icon", - startIconOnClick = { - state.eventSink(RecordDetailUiEvent.OnCloseClicked) - }, + ReedScaffold( + modifier = modifier.fillMaxSize(), + topBar = { + ReedTopAppBar( + title = stringResource(R.string.review_detail_title), + startIconRes = designR.drawable.ic_close, + startIconDescription = "Close Icon", + startIconOnClick = { + state.eventSink(RecordDetailUiEvent.OnCloseClicked) + }, + ) + }, + containerColor = White, + ) { innerPadding -> + ReviewDetailContent( + state = state, + innerPadding = innerPadding, ) - ReviewDetailContent(state = state, modifier = modifier) } } @Composable -private fun ReviewDetailContent(state: RecordDetailUiState, modifier: Modifier = Modifier) { +private fun ReviewDetailContent( + state: RecordDetailUiState, + innerPadding: PaddingValues, + modifier: Modifier = Modifier +) { Column( - modifier = Modifier + modifier = modifier .fillMaxSize() - .background(White), + .padding(innerPadding), ) { Row( modifier = modifier diff --git a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomePresenter.kt b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomePresenter.kt index a9418106..573201fb 100644 --- a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomePresenter.kt +++ b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomePresenter.kt @@ -78,6 +78,14 @@ class HomePresenter @AssistedInject constructor( is HomeUiEvent.OnBookDetailClick -> { navigator.goTo(BookDetailScreen("")) } + + is HomeUiEvent.OnTabSelected -> { + navigator.resetRoot( + newRoot = event.tab.screen, + saveState = true, + restoreState = true, + ) + } } } diff --git a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt index b0beabc2..6a768359 100644 --- a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt +++ b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUi.kt @@ -12,13 +12,11 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.stringResource @@ -26,15 +24,17 @@ import androidx.compose.ui.unit.dp import com.ninecraft.booket.core.designsystem.DevicePreview import com.ninecraft.booket.core.designsystem.theme.HomeBg import com.ninecraft.booket.core.designsystem.theme.ReedTheme -import com.ninecraft.booket.core.designsystem.theme.White +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.feature.home.component.BookCard import com.ninecraft.booket.feature.home.component.EmptyBookCard import com.ninecraft.booket.feature.home.component.HomeBanner import com.ninecraft.booket.feature.home.component.HomeHeader import com.ninecraft.booket.feature.screens.HomeScreen +import com.ninecraft.booket.feature.screens.component.MainBottomBar +import com.ninecraft.booket.feature.screens.component.MainTab import com.slack.circuit.codegen.annotations.CircuitInject import dagger.hilt.android.components.ActivityRetainedComponent -import tech.thdev.compose.exteions.system.ui.controller.rememberSystemUiController +import kotlinx.collections.immutable.toImmutableList @CircuitInject(HomeScreen::class, ActivityRetainedComponent::class) @Composable @@ -42,45 +42,42 @@ internal fun HomeUi( state: HomeUiState, modifier: Modifier = Modifier, ) { - val systemUiController = rememberSystemUiController() - - DisposableEffect(systemUiController) { - systemUiController.setStatusBarColor( - color = HomeBg, - darkIcons = true, - ) + HandleHomeSideEffects(state = state) - onDispose { - systemUiController.setStatusBarColor( - color = White, - darkIcons = true, + ReedScaffold( + modifier = modifier.fillMaxSize(), + bottomBar = { + MainBottomBar( + tabs = MainTab.entries.toImmutableList(), + currentTab = MainTab.HOME, + onTabSelected = { tab -> + state.eventSink(HomeUiEvent.OnTabSelected(tab)) + }, + ) + }, + ) { innerPadding -> + Column( + modifier = Modifier + .fillMaxSize() + .background(HomeBg) + .padding(innerPadding), + ) { + HomeHeader( + onSettingsClick = { + state.eventSink(HomeUiEvent.OnSettingsClick) + }, + ) + HomeBanner( + onBookRegisterClick = { + state.eventSink(HomeUiEvent.OnBookRegisterClick) + }, + ) + HomeContent( + state = state, + modifier = Modifier, ) } } - - HandleHomeSideEffects(state = state) - - Column( - modifier = modifier - .fillMaxSize() - .background(HomeBg) - .statusBarsPadding(), - ) { - HomeHeader( - onSettingsClick = { - state.eventSink(HomeUiEvent.OnSettingsClick) - }, - ) - HomeBanner( - onBookRegisterClick = { - state.eventSink(HomeUiEvent.OnBookRegisterClick) - }, - ) - HomeContent( - state = state, - modifier = modifier, - ) - } } @Composable diff --git a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt index 0961765f..b3d4fcab 100644 --- a/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt +++ b/feature/home/src/main/kotlin/com/ninecraft/booket/feature/home/HomeUiState.kt @@ -2,6 +2,7 @@ package com.ninecraft.booket.feature.home import androidx.compose.runtime.Immutable import com.ninecraft.booket.core.model.RecentBookModel +import com.ninecraft.booket.feature.screens.component.MainTab import com.slack.circuit.runtime.CircuitUiEvent import com.slack.circuit.runtime.CircuitUiState import kotlinx.collections.immutable.ImmutableList @@ -27,4 +28,5 @@ sealed interface HomeUiEvent : CircuitUiEvent { data object OnBookRegisterClick : HomeUiEvent data class OnRecordButtonClick(val userBookId: String) : HomeUiEvent data object OnBookDetailClick : HomeUiEvent + data class OnTabSelected(val tab: MainTab) : HomeUiEvent } diff --git a/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryPresenter.kt b/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryPresenter.kt index d13bf479..455fc27f 100644 --- a/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryPresenter.kt +++ b/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryPresenter.kt @@ -131,6 +131,14 @@ class LibraryPresenter @AssistedInject constructor( is LibraryUiEvent.OnRetryClick -> { filterLibraryBooks(status = currentFilter.getApiValue(), page = currentPage, size = PAGE_SIZE) } + + is LibraryUiEvent.OnTabSelected -> { + navigator.resetRoot( + newRoot = event.tab.screen, + saveState = true, + restoreState = true, + ) + } } } diff --git a/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUi.kt b/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUi.kt index 38722a33..4185fb32 100644 --- a/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUi.kt +++ b/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUi.kt @@ -8,12 +8,11 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.items import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -23,18 +22,20 @@ import com.ninecraft.booket.core.designsystem.component.button.ReedButton import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorStyle import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle import com.ninecraft.booket.core.designsystem.theme.ReedTheme -import com.ninecraft.booket.core.designsystem.theme.White import com.ninecraft.booket.core.model.LibraryBookSummaryModel +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.core.ui.component.InfinityLazyColumn import com.ninecraft.booket.core.ui.component.LoadStateFooter import com.ninecraft.booket.feature.library.component.FilterChipGroup import com.ninecraft.booket.feature.library.component.LibraryBookItem import com.ninecraft.booket.feature.library.component.LibraryHeader import com.ninecraft.booket.feature.screens.LibraryScreen +import com.ninecraft.booket.feature.screens.component.MainBottomBar +import com.ninecraft.booket.feature.screens.component.MainTab import com.slack.circuit.codegen.annotations.CircuitInject import dagger.hilt.android.components.ActivityRetainedComponent import kotlinx.collections.immutable.persistentListOf -import tech.thdev.compose.exteions.system.ui.controller.rememberSystemUiController +import kotlinx.collections.immutable.toImmutableList @CircuitInject(LibraryScreen::class, ActivityRetainedComponent::class) @Composable @@ -42,39 +43,42 @@ internal fun LibraryUi( state: LibraryUiState, modifier: Modifier = Modifier, ) { - val systemUiController = rememberSystemUiController() - - DisposableEffect(systemUiController) { - systemUiController.setStatusBarColor( - color = White, - darkIcons = true, - ) - onDispose {} - } - HandleLibrarySideEffects( state = state, eventSink = state.eventSink, ) - Column( - modifier = modifier - .fillMaxSize() - .statusBarsPadding(), - ) { - LibraryHeader( - onSearchClick = { - state.eventSink(LibraryUiEvent.OnLibrarySearchClick) - }, - onSettingClick = { - state.eventSink(LibraryUiEvent.OnSettingsClick) - }, - ) + ReedScaffold( + modifier = modifier.fillMaxSize(), + bottomBar = { + MainBottomBar( + tabs = MainTab.entries.toImmutableList(), + currentTab = MainTab.LIBRARY, + onTabSelected = { tab -> + state.eventSink(LibraryUiEvent.OnTabSelected(tab)) + }, + ) + }, + ) { innerPadding -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), + ) { + LibraryHeader( + onSearchClick = { + state.eventSink(LibraryUiEvent.OnLibrarySearchClick) + }, + onSettingClick = { + state.eventSink(LibraryUiEvent.OnSettingsClick) + }, + ) - LibraryContent( - state = state, - modifier = modifier, - ) + LibraryContent( + state = state, + modifier = Modifier, + ) + } } } diff --git a/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUiState.kt b/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUiState.kt index 4d5b0497..e3e5df09 100644 --- a/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUiState.kt +++ b/feature/library/src/main/kotlin/com/ninecraft/booket/feature/library/LibraryUiState.kt @@ -3,6 +3,7 @@ package com.ninecraft.booket.feature.library import androidx.compose.runtime.Immutable import com.ninecraft.booket.core.model.LibraryBookSummaryModel import com.ninecraft.booket.core.ui.component.FooterState +import com.ninecraft.booket.feature.screens.component.MainTab import com.slack.circuit.runtime.CircuitUiEvent import com.slack.circuit.runtime.CircuitUiState import kotlinx.collections.immutable.ImmutableList @@ -40,6 +41,7 @@ sealed interface LibraryUiEvent : CircuitUiEvent { data object OnLoadMore : LibraryUiEvent data object OnRetryClick : LibraryUiEvent data class OnFilterClick(val filterOption: LibraryFilterOption) : LibraryUiEvent + data class OnTabSelected(val tab: MainTab) : LibraryUiEvent } data class LibraryFilterChip( diff --git a/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginPresenter.kt b/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginPresenter.kt index 4b62d508..522cb880 100644 --- a/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginPresenter.kt +++ b/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginPresenter.kt @@ -7,7 +7,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import com.ninecraft.booket.core.data.api.repository.AuthRepository import com.ninecraft.booket.core.data.api.repository.UserRepository -import com.ninecraft.booket.feature.screens.BottomNavigationScreen +import com.ninecraft.booket.feature.screens.HomeScreen import com.ninecraft.booket.feature.screens.LoginScreen import com.ninecraft.booket.feature.screens.TermsAgreementScreen import com.orhanobut.logger.Logger @@ -38,7 +38,7 @@ class LoginPresenter @AssistedInject constructor( userRepository.getUserProfile() .onSuccess { userProfile -> if (userProfile.termsAgreed) { - navigator.resetRoot(BottomNavigationScreen) + navigator.resetRoot(HomeScreen) } else { navigator.resetRoot(TermsAgreementScreen) } diff --git a/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginUi.kt b/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginUi.kt index 1601705a..105e04a3 100644 --- a/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginUi.kt +++ b/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginUi.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Icon import androidx.compose.material3.Text @@ -24,6 +23,7 @@ import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorSt import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle import com.ninecraft.booket.core.designsystem.theme.ReedTheme import com.ninecraft.booket.core.designsystem.theme.White +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.feature.screens.LoginScreen import com.slack.circuit.codegen.annotations.CircuitInject import dagger.hilt.android.components.ActivityRetainedComponent @@ -39,15 +39,18 @@ internal fun LoginUi( eventSink = state.eventSink, ) - Column( - modifier = modifier - .fillMaxSize() - .background(White) - .systemBarsPadding(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - ) { - Box(modifier = modifier.fillMaxSize()) { + ReedScaffold( + modifier = modifier.fillMaxSize(), + ) { innerPadding -> + Column( + modifier = Modifier + .fillMaxSize() + .background(White) + .padding(innerPadding), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Box(modifier = Modifier.fillMaxSize()) { Text( text = "로그인", modifier = Modifier.align(Alignment.Center), @@ -85,6 +88,7 @@ internal fun LoginUi( } } } +} @DevicePreview @Composable diff --git a/feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementPresenter.kt b/feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementPresenter.kt index 5ffa3ffe..9d2417f2 100644 --- a/feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementPresenter.kt +++ b/feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementPresenter.kt @@ -9,7 +9,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import com.ninecraft.booket.core.common.constants.WebViewConstants import com.ninecraft.booket.core.data.api.repository.AuthRepository -import com.ninecraft.booket.feature.screens.BottomNavigationScreen +import com.ninecraft.booket.feature.screens.HomeScreen import com.ninecraft.booket.feature.screens.TermsAgreementScreen import com.ninecraft.booket.feature.screens.WebViewScreen import com.orhanobut.logger.Logger @@ -70,7 +70,7 @@ class TermsAgreementPresenter @AssistedInject constructor( scope.launch { authRepository.agreeTerms(true) .onSuccess { - navigator.resetRoot(BottomNavigationScreen) + navigator.resetRoot(HomeScreen) }.onFailure { exception -> exception.message?.let { Logger.e(it) } sideEffect = exception.message?.let { diff --git a/feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementUi.kt b/feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementUi.kt index 01b57d26..b130012e 100644 --- a/feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementUi.kt +++ b/feature/login/src/main/kotlin/com/ninecraft/booket/feature/termsagreement/TermsAgreementUi.kt @@ -1,6 +1,5 @@ package com.ninecraft.booket.feature.termsagreement -import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -9,7 +8,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text @@ -27,6 +25,7 @@ import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle import com.ninecraft.booket.core.designsystem.component.checkbox.SquareCheckBox import com.ninecraft.booket.core.designsystem.theme.ReedTheme import com.ninecraft.booket.core.designsystem.theme.White +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.feature.login.R import com.ninecraft.booket.feature.screens.TermsAgreementScreen import com.ninecraft.booket.feature.termsagreement.component.TermItem @@ -44,102 +43,106 @@ internal fun TermsAgreementUi( val termsTitles = stringArrayResource(id = R.array.terms_agreement_items) - Column( - modifier = modifier - .fillMaxSize() - .background(White) - .systemBarsPadding(), - ) { - Spacer(modifier = Modifier.height(76.dp)) + ReedScaffold( + modifier = modifier.fillMaxSize(), + containerColor = White, + ) { innerPadding -> Column( modifier = Modifier - .weight(1f) - .padding(horizontal = ReedTheme.spacing.spacing5), + .fillMaxSize() + .padding(innerPadding), ) { - Text( - text = stringResource(R.string.terms_agreement_title), - color = ReedTheme.colors.contentPrimary, - style = ReedTheme.typography.title2SemiBold, - ) - Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) - Row( + Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing3)) + Column( modifier = Modifier - .fillMaxWidth() - .border( - width = 1.dp, - color = ReedTheme.colors.contentBrand, - shape = RoundedCornerShape(ReedTheme.radius.sm), - ) - .noRippleClickable { - state.eventSink(TermsAgreementUiEvent.OnAllTermsAgreedClick) - } - .padding( - horizontal = ReedTheme.spacing.spacing4, - vertical = ReedTheme.spacing.spacing5, - ), - verticalAlignment = Alignment.CenterVertically, + .weight(1f) + .padding(horizontal = ReedTheme.spacing.spacing5), ) { - SquareCheckBox( - checked = state.isAllAgreed, - onCheckedChange = { - state.eventSink(TermsAgreementUiEvent.OnAllTermsAgreedClick) - }, - ) - Spacer(modifier = Modifier.width(ReedTheme.spacing.spacing4)) Text( - text = stringResource(R.string.terms_agreement_all), + text = stringResource(R.string.terms_agreement_title), color = ReedTheme.colors.contentPrimary, - style = ReedTheme.typography.headline1SemiBold, + style = ReedTheme.typography.title2SemiBold, + ) + Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) + Row( + modifier = Modifier + .fillMaxWidth() + .border( + width = 1.dp, + color = ReedTheme.colors.contentBrand, + shape = RoundedCornerShape(ReedTheme.radius.sm), + ) + .noRippleClickable { + state.eventSink(TermsAgreementUiEvent.OnAllTermsAgreedClick) + } + .padding( + horizontal = ReedTheme.spacing.spacing4, + vertical = ReedTheme.spacing.spacing5, + ), + verticalAlignment = Alignment.CenterVertically, + ) { + SquareCheckBox( + checked = state.isAllAgreed, + onCheckedChange = { + state.eventSink(TermsAgreementUiEvent.OnAllTermsAgreedClick) + }, + ) + Spacer(modifier = Modifier.width(ReedTheme.spacing.spacing4)) + Text( + text = stringResource(R.string.terms_agreement_all), + color = ReedTheme.colors.contentPrimary, + style = ReedTheme.typography.headline1SemiBold, + ) + } + Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing5)) + TermItem( + title = termsTitles[0], + checked = state.agreedTerms[0], + onCheckClick = { + state.eventSink(TermsAgreementUiEvent.OnTermItemClick(0)) + }, + onDetailClick = { + state.eventSink(TermsAgreementUiEvent.OnTermClick) + }, + ) + Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) + TermItem( + title = termsTitles[1], + checked = state.agreedTerms[1], + onCheckClick = { + state.eventSink(TermsAgreementUiEvent.OnTermItemClick(1)) + }, + onDetailClick = { + state.eventSink(TermsAgreementUiEvent.OnPolicyClick) + }, + ) + Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) + TermItem( + title = termsTitles[2], + checked = state.agreedTerms[2], + hasDetailAction = false, + onCheckClick = { + state.eventSink(TermsAgreementUiEvent.OnTermItemClick(2)) + }, ) } - Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing5)) - TermItem( - title = termsTitles[0], - checked = state.agreedTerms[0], - onCheckClick = { - state.eventSink(TermsAgreementUiEvent.OnTermItemClick(0)) - }, - onDetailClick = { - state.eventSink(TermsAgreementUiEvent.OnTermClick) - }, - ) - Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) - TermItem( - title = termsTitles[1], - checked = state.agreedTerms[1], - onCheckClick = { - state.eventSink(TermsAgreementUiEvent.OnTermItemClick(1)) - }, - onDetailClick = { - state.eventSink(TermsAgreementUiEvent.OnPolicyClick) - }, - ) - Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) - TermItem( - title = termsTitles[2], - checked = state.agreedTerms[2], - hasDetailAction = false, - onCheckClick = { - state.eventSink(TermsAgreementUiEvent.OnTermItemClick(2)) + ReedButton( + onClick = { + state.eventSink(TermsAgreementUiEvent.OnStartButtonClick) }, + sizeStyle = largeButtonStyle, + colorStyle = ReedButtonColorStyle.PRIMARY, + modifier = Modifier + .fillMaxWidth() + .padding( + start = ReedTheme.spacing.spacing5, + end = ReedTheme.spacing.spacing5, + bottom = ReedTheme.spacing.spacing4, + ), + enabled = state.isAllAgreed, + text = stringResource(R.string.terms_agreement_button_start), ) } - ReedButton( - onClick = { - state.eventSink(TermsAgreementUiEvent.OnStartButtonClick) - }, - sizeStyle = largeButtonStyle, - colorStyle = ReedButtonColorStyle.PRIMARY, - modifier = Modifier - .fillMaxWidth() - .padding( - start = ReedTheme.spacing.spacing5, - end = ReedTheme.spacing.spacing5, - bottom = ReedTheme.spacing.spacing4, - ), - enabled = state.isAllAgreed, - text = stringResource(R.string.terms_agreement_button_start), - ) } } diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt index 489fcc7d..f20f85e9 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt +++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/MainActivity.kt @@ -7,9 +7,9 @@ import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import com.ninecraft.booket.core.designsystem.theme.ReedTheme -import com.ninecraft.booket.core.designsystem.theme.White import com.ninecraft.booket.feature.screens.SplashScreen import com.slack.circuit.backstack.rememberSaveableBackStack import com.slack.circuit.foundation.Circuit @@ -35,8 +35,9 @@ class MainActivity : ComponentActivity() { DisposableEffect(systemUiController) { systemUiController.setSystemBarsColor( - color = White, + color = Color.Transparent, darkIcons = true, + isNavigationBarContrastEnforced = false, ) onDispose {} diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationPresenter.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationPresenter.kt deleted file mode 100644 index bf7b2aeb..00000000 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationPresenter.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.ninecraft.booket.feature.main.bottomnavigation - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import com.ninecraft.booket.feature.main.component.getCurrentTab -import com.ninecraft.booket.feature.screens.BottomNavigationScreen -import com.ninecraft.booket.feature.screens.HomeScreen -import com.slack.circuit.backstack.rememberSaveableBackStack -import com.slack.circuit.codegen.annotations.CircuitInject -import com.slack.circuit.foundation.rememberCircuitNavigator -import com.slack.circuit.runtime.Navigator -import com.slack.circuit.runtime.presenter.Presenter -import dagger.assisted.Assisted -import dagger.assisted.AssistedFactory -import dagger.assisted.AssistedInject -import dagger.hilt.android.components.ActivityRetainedComponent - -class BottomNavigationPresenter @AssistedInject constructor( - @Assisted private val rootNavigator: Navigator, -) : Presenter { - - @Composable - override fun present(): BottomNavigationUiState { - val childBackStack = rememberSaveableBackStack(root = HomeScreen) - val childNavigator = rememberCircuitNavigator(childBackStack) - val delegateNavigator = remember(childNavigator, rootNavigator) { - DelegateNavigator(childNavigator, rootNavigator) - } - val currentTab = getCurrentTab(childBackStack) - - fun handleEvent(event: BottomNavigationUiEvent) { - when (event) { - is BottomNavigationUiEvent.OnTabSelected -> { - childNavigator.resetRoot( - newRoot = event.tab.screen, - saveState = true, - restoreState = true, - ) - } - } - } - - return BottomNavigationUiState( - backStack = childBackStack, - navigator = delegateNavigator, - currentTab = currentTab, - eventSink = ::handleEvent, - ) - } - - @CircuitInject(BottomNavigationScreen::class, ActivityRetainedComponent::class) - @AssistedFactory - fun interface Factory { - fun create(rootNavigator: Navigator): BottomNavigationPresenter - } -} diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUi.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUi.kt deleted file mode 100644 index e16017dd..00000000 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUi.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.ninecraft.booket.feature.main.bottomnavigation - -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.ninecraft.booket.core.ui.ReedScaffold -import com.ninecraft.booket.feature.main.component.MainBottomBar -import com.ninecraft.booket.feature.main.component.MainTab -import com.ninecraft.booket.feature.screens.BottomNavigationScreen -import com.slack.circuit.codegen.annotations.CircuitInject -import com.slack.circuit.foundation.NavigableCircuitContent -import dagger.hilt.android.components.ActivityRetainedComponent -import kotlinx.collections.immutable.toImmutableList - -@CircuitInject(BottomNavigationScreen::class, ActivityRetainedComponent::class) -@Composable -fun BottomNavigationUi( - state: BottomNavigationUiState, - modifier: Modifier = Modifier, -) { - ReedScaffold( - modifier = modifier.fillMaxSize(), - bottomBar = { - MainBottomBar( - tabs = MainTab.entries.toImmutableList(), - currentTab = state.currentTab, - onTabSelected = { tab -> - state.eventSink(BottomNavigationUiEvent.OnTabSelected(tab)) - }, - ) - }, - contentWindowInsets = WindowInsets(top = 0.dp), - ) { innerPadding -> - NavigableCircuitContent( - navigator = state.navigator, - backStack = state.backStack, - modifier = Modifier - .fillMaxSize() - .padding(innerPadding), - ) - } -} diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUiState.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUiState.kt deleted file mode 100644 index a01fc304..00000000 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/BottomNavigationUiState.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.ninecraft.booket.feature.main.bottomnavigation - -import com.ninecraft.booket.feature.main.component.MainTab -import com.slack.circuit.backstack.SaveableBackStack -import com.slack.circuit.runtime.CircuitUiState -import com.slack.circuit.runtime.Navigator - -data class BottomNavigationUiState( - val backStack: SaveableBackStack, - val navigator: Navigator, - val currentTab: MainTab?, - val eventSink: (BottomNavigationUiEvent) -> Unit, -) : CircuitUiState - -sealed interface BottomNavigationUiEvent { - data class OnTabSelected(val tab: MainTab) : BottomNavigationUiEvent -} diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/DelegateNavigator.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/DelegateNavigator.kt deleted file mode 100644 index e3b9f581..00000000 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/bottomnavigation/DelegateNavigator.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.ninecraft.booket.feature.main.bottomnavigation - -import com.ninecraft.booket.feature.main.component.MainTab -import com.slack.circuit.runtime.Navigator -import com.slack.circuit.runtime.screen.PopResult -import com.slack.circuit.runtime.screen.Screen -import kotlinx.collections.immutable.ImmutableList - -class DelegateNavigator( - private val childNavigator: Navigator, - private val rootNavigator: Navigator, -) : Navigator { - private fun isMainTabScreen(screen: Screen): Boolean { - return MainTab.entries.any { it.screen::class == screen::class } - } - - override fun goTo(screen: Screen): Boolean { - return if (isMainTabScreen(screen)) { - childNavigator.goTo(screen) - } else { - rootNavigator.goTo(screen) - } - } - - override fun pop(result: PopResult?): Screen? { - return childNavigator.pop(result) - } - - override fun peek(): Screen? { - return childNavigator.peek() - } - - override fun resetRoot( - newRoot: Screen, - saveState: Boolean, - restoreState: Boolean, - ): ImmutableList { - return if (isMainTabScreen(newRoot)) { - childNavigator.resetRoot(newRoot, saveState, restoreState) - } else { - rootNavigator.resetRoot(newRoot, saveState, restoreState) - } - } - - override fun peekBackStack(): ImmutableList { - return childNavigator.peekBackStack() - } -} diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt index f956a7a1..1db7ec38 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt +++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashPresenter.kt @@ -9,7 +9,7 @@ import com.ninecraft.booket.core.data.api.repository.AuthRepository import com.ninecraft.booket.core.data.api.repository.UserRepository import com.ninecraft.booket.core.model.AutoLoginState import com.ninecraft.booket.core.model.OnboardingState -import com.ninecraft.booket.feature.screens.BottomNavigationScreen +import com.ninecraft.booket.feature.screens.HomeScreen import com.ninecraft.booket.feature.screens.LoginScreen import com.ninecraft.booket.feature.screens.OnboardingScreen import com.ninecraft.booket.feature.screens.SplashScreen @@ -38,7 +38,7 @@ class SplashPresenter @AssistedInject constructor( var isSplashTimeCompleted by rememberRetained { mutableStateOf(false) } LaunchedEffect(Unit) { - delay(3000L) + delay(1000L) isSplashTimeCompleted = true } @@ -53,7 +53,7 @@ class SplashPresenter @AssistedInject constructor( OnboardingState.COMPLETED -> { when (autoLoginState) { AutoLoginState.LOGGED_IN -> { - navigator.resetRoot(BottomNavigationScreen) + navigator.resetRoot(HomeScreen) } AutoLoginState.NOT_LOGGED_IN -> { diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt index f86a622c..d6cf9dbc 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt +++ b/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/splash/SplashUi.kt @@ -14,13 +14,12 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.ninecraft.booket.core.designsystem.DevicePreview -import com.ninecraft.booket.core.designsystem.theme.Green500 import com.ninecraft.booket.core.designsystem.theme.ReedTheme -import com.ninecraft.booket.core.designsystem.theme.White import com.ninecraft.booket.feature.main.R import com.ninecraft.booket.feature.screens.SplashScreen import com.slack.circuit.codegen.annotations.CircuitInject @@ -36,14 +35,16 @@ fun SplashUi( DisposableEffect(systemUiController) { systemUiController.setSystemBarsColor( - color = Green500, + color = Color.Transparent, darkIcons = false, + isNavigationBarContrastEnforced = false, ) onDispose { systemUiController.setSystemBarsColor( - color = White, + color = Color.Transparent, darkIcons = true, + isNavigationBarContrastEnforced = false, ) } } diff --git a/feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt b/feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt index 9be55bb5..7e95996e 100644 --- a/feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt +++ b/feature/onboarding/src/main/kotlin/com/ninecraft/booket/feature/onboarding/OnboardingUi.kt @@ -18,7 +18,8 @@ import com.ninecraft.booket.core.designsystem.component.button.ReedButton import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorStyle import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle import com.ninecraft.booket.core.designsystem.theme.ReedTheme -import com.ninecraft.booket.core.ui.component.ReedFullScreen +import com.ninecraft.booket.core.designsystem.theme.White +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.feature.onboarding.component.OnboardingPage import com.ninecraft.booket.feature.onboarding.component.PagerIndicator import com.ninecraft.booket.feature.screens.OnboardingScreen @@ -31,9 +32,14 @@ internal fun OnboardingUi( state: OnboardingUiState, modifier: Modifier = Modifier, ) { - ReedFullScreen(modifier = modifier) { + ReedScaffold( + modifier = modifier.fillMaxSize(), + containerColor = White, + ) { innerPadding -> Column( - modifier = Modifier.fillMaxSize(), + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), horizontalAlignment = Alignment.CenterHorizontally, ) { HorizontalPager( diff --git a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt index 626298e6..2f3f5127 100644 --- a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt +++ b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt @@ -18,21 +18,18 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon -import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect @@ -57,6 +54,7 @@ import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle import com.ninecraft.booket.core.designsystem.theme.Neutral950 import com.ninecraft.booket.core.designsystem.theme.ReedTheme import com.ninecraft.booket.core.designsystem.theme.White +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.core.ui.component.ReedCloseTopAppBar import com.ninecraft.booket.core.ui.component.ReedDialog import com.ninecraft.booket.feature.record.R @@ -65,26 +63,17 @@ import com.ninecraft.booket.feature.record.ocr.component.SentenceBox import com.ninecraft.booket.feature.screens.OcrScreen import com.slack.circuit.codegen.annotations.CircuitInject import dagger.hilt.android.components.ActivityRetainedComponent -import tech.thdev.compose.exteions.system.ui.controller.rememberSystemUiController import com.ninecraft.booket.core.designsystem.R as designR @CircuitInject(OcrScreen::class, ActivityRetainedComponent::class) @Composable -internal fun Ocr( +internal fun OcrUi( state: OcrUiState, modifier: Modifier = Modifier, ) { - Scaffold(contentWindowInsets = WindowInsets(0.dp)) { innerPadding -> - Box( - modifier = modifier - .fillMaxSize() - .padding(innerPadding), - ) { - when (state.currentUi) { - OcrUi.CAMERA -> CameraPreview(state = state, modifier = modifier) - OcrUi.RESULT -> TextScanResult(state = state, modifier = modifier) - } - } + when (state.currentUi) { + OcrUi.CAMERA -> CameraPreview(state = state, modifier = modifier) + OcrUi.RESULT -> TextScanResult(state = state, modifier = modifier) } } @@ -124,20 +113,6 @@ private fun CameraPreview( } } - val systemUiController = rememberSystemUiController() - - DisposableEffect(systemUiController) { - systemUiController.setSystemBarsColor( - color = Neutral950, - darkIcons = false, - ) - onDispose { - systemUiController.setSystemBarsColor( - color = White, - darkIcons = true, - ) - } - } LaunchedEffect(Unit) { val granted = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED @@ -160,16 +135,10 @@ private fun CameraPreview( } } - Box( - modifier = modifier - .fillMaxSize() - .background(Neutral950) - .systemBarsPadding(), - ) { - Column( - modifier = Modifier.fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally, - ) { + ReedScaffold( + modifier = modifier.fillMaxSize(), + containerColor = Neutral950, + topBar = { ReedCloseTopAppBar( modifier = Modifier.background(color = Color.Black), isDark = true, @@ -177,74 +146,86 @@ private fun CameraPreview( state.eventSink(OcrUiEvent.OnCloseClick) }, ) - Text( - text = stringResource(R.string.ocr_guide), - color = ReedTheme.colors.contentInverse, - textAlign = TextAlign.Center, - style = ReedTheme.typography.headline2Medium, - ) - } - - if (state.hasPermission) { - Box( - modifier = Modifier - .fillMaxWidth() - .background(White) - .aspectRatio(1f) - .align(Alignment.Center), - ) { - AndroidView( - modifier = Modifier.fillMaxSize(), - factory = { context -> - PreviewView(context).apply { - layoutParams = LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, - ) - clipToOutline = true - implementationMode = PreviewView.ImplementationMode.COMPATIBLE - scaleType = PreviewView.ScaleType.FILL_CENTER - controller = cameraController - } - }, - ) - } - CameraFrame(modifier = Modifier.align(Alignment.Center)) - } - - Column( - modifier = Modifier.align(Alignment.BottomCenter), - horizontalAlignment = Alignment.CenterHorizontally, + }, + ) { innerPadding -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), ) { - if (state.isTextDetectionFailed) { + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { Text( - text = stringResource(R.string.ocr_error_text_detection_failed), - color = ReedTheme.colors.contentError, + text = stringResource(R.string.ocr_guide), + color = ReedTheme.colors.contentInverse, textAlign = TextAlign.Center, - style = ReedTheme.typography.label2Regular, + style = ReedTheme.typography.headline2Medium, ) - Spacer(modifier = Modifier.height(22.dp)) } - Button( - onClick = { - state.eventSink(OcrUiEvent.OnCaptureButtonClick) - }, - modifier = Modifier.size(72.dp), - shape = CircleShape, - colors = ButtonDefaults.buttonColors( - containerColor = ReedTheme.colors.bgPrimary, - contentColor = White, - ), - contentPadding = PaddingValues(ReedTheme.spacing.spacing0), + if (state.hasPermission) { + Box( + modifier = Modifier + .fillMaxWidth() + .background(White) + .aspectRatio(1f) + .align(Alignment.Center), + ) { + AndroidView( + modifier = Modifier.fillMaxSize(), + factory = { context -> + PreviewView(context).apply { + layoutParams = LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, + ) + clipToOutline = true + implementationMode = PreviewView.ImplementationMode.COMPATIBLE + scaleType = PreviewView.ScaleType.FILL_CENTER + controller = cameraController + } + }, + ) + } + CameraFrame(modifier = Modifier.align(Alignment.Center)) + } + + Column( + modifier = Modifier.align(Alignment.BottomCenter), + horizontalAlignment = Alignment.CenterHorizontally, ) { - Icon( - imageVector = ImageVector.vectorResource(designR.drawable.ic_maximize), - contentDescription = "Scan Icon", - modifier = Modifier.size(ReedTheme.spacing.spacing8), - ) + if (state.isTextDetectionFailed) { + Text( + text = stringResource(R.string.ocr_error_text_detection_failed), + color = ReedTheme.colors.contentError, + textAlign = TextAlign.Center, + style = ReedTheme.typography.label2Regular, + ) + Spacer(modifier = Modifier.height(22.dp)) + } + + Button( + onClick = { + state.eventSink(OcrUiEvent.OnCaptureButtonClick) + }, + modifier = Modifier.size(72.dp), + shape = CircleShape, + colors = ButtonDefaults.buttonColors( + containerColor = ReedTheme.colors.bgPrimary, + contentColor = White, + ), + contentPadding = PaddingValues(ReedTheme.spacing.spacing0), + ) { + Icon( + imageVector = ImageVector.vectorResource(designR.drawable.ic_maximize), + contentDescription = "Scan Icon", + modifier = Modifier.size(ReedTheme.spacing.spacing8), + ) + } + Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) } - Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) } } @@ -268,63 +249,69 @@ private fun TextScanResult( state: OcrUiState, modifier: Modifier = Modifier, ) { - Column( - modifier = modifier - .fillMaxSize() - .background(White) - .systemBarsPadding(), - ) { - ReedCloseTopAppBar( - title = stringResource(R.string.ocr_sentence_selection), - onClose = { - state.eventSink(OcrUiEvent.OnCloseClick) - }, - ) - LazyColumn( + ReedScaffold( + modifier = modifier.fillMaxSize(), + containerColor = White, + topBar = { + ReedCloseTopAppBar( + title = stringResource(R.string.ocr_sentence_selection), + onClose = { + state.eventSink(OcrUiEvent.OnCloseClick) + }, + ) + }, + ) { innerPadding -> + Column( modifier = Modifier - .weight(1f) - .padding(horizontal = ReedTheme.spacing.spacing3), - verticalArrangement = Arrangement.spacedBy(ReedTheme.spacing.spacing2), + .fillMaxSize() + .padding(innerPadding), ) { - items(state.sentenceList.size) { index -> - SentenceBox( + LazyColumn( + modifier = Modifier + .weight(1f) + .padding(horizontal = ReedTheme.spacing.spacing3), + verticalArrangement = Arrangement.spacedBy(ReedTheme.spacing.spacing2), + ) { + items(state.sentenceList.size) { index -> + SentenceBox( + onClick = { + state.eventSink(OcrUiEvent.OnSentenceSelected(index)) + }, + sentence = state.sentenceList[index], + isSelected = state.selectedIndices.contains(index), + ) + } + } + Row( + modifier = Modifier + .fillMaxWidth() + .padding( + horizontal = ReedTheme.spacing.spacing5, + vertical = ReedTheme.spacing.spacing4, + ), + ) { + ReedButton( onClick = { - state.eventSink(OcrUiEvent.OnSentenceSelected(index)) + state.eventSink(OcrUiEvent.OnReCaptureButtonClick) }, - sentence = state.sentenceList[index], - isSelected = state.selectedIndices.contains(index), + sizeStyle = largeButtonStyle, + colorStyle = ReedButtonColorStyle.SECONDARY, + modifier = Modifier.weight(1f), + text = stringResource(R.string.ocr_recapture), + ) + Spacer(modifier = Modifier.width(ReedTheme.spacing.spacing2)) + ReedButton( + onClick = { + state.eventSink(OcrUiEvent.OnSelectionConfirmed) + }, + sizeStyle = largeButtonStyle, + colorStyle = ReedButtonColorStyle.PRIMARY, + enabled = state.selectedIndices.isNotEmpty(), + modifier = Modifier.weight(1f), + text = stringResource(R.string.ocr_selection_confirm), ) } } - Row( - modifier = Modifier - .fillMaxWidth() - .padding( - horizontal = ReedTheme.spacing.spacing5, - vertical = ReedTheme.spacing.spacing4, - ), - ) { - ReedButton( - onClick = { - state.eventSink(OcrUiEvent.OnReCaptureButtonClick) - }, - sizeStyle = largeButtonStyle, - colorStyle = ReedButtonColorStyle.SECONDARY, - modifier = Modifier.weight(1f), - text = stringResource(R.string.ocr_recapture), - ) - Spacer(modifier = Modifier.width(ReedTheme.spacing.spacing2)) - ReedButton( - onClick = { - state.eventSink(OcrUiEvent.OnSelectionConfirmed) - }, - sizeStyle = largeButtonStyle, - colorStyle = ReedButtonColorStyle.PRIMARY, - enabled = state.selectedIndices.isNotEmpty(), - modifier = Modifier.weight(1f), - text = stringResource(R.string.ocr_selection_confirm), - ) - } } if (state.isRecaptureDialogVisible) { diff --git a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt index 5ca9b1d8..24eb3b7b 100644 --- a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt +++ b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt @@ -3,6 +3,7 @@ package com.ninecraft.booket.feature.record.register import androidx.activity.compose.BackHandler import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -20,9 +21,10 @@ import com.ninecraft.booket.core.designsystem.component.button.ReedButton import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorStyle import com.ninecraft.booket.core.designsystem.component.button.largeButtonStyle import com.ninecraft.booket.core.designsystem.theme.ReedTheme +import com.ninecraft.booket.core.designsystem.theme.White +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar import com.ninecraft.booket.core.ui.component.ReedDialog -import com.ninecraft.booket.core.ui.component.ReedFullScreen import com.ninecraft.booket.feature.record.R import com.ninecraft.booket.feature.record.step.EmotionStep import com.ninecraft.booket.feature.record.step.ImpressionStep @@ -43,47 +45,56 @@ internal fun RecordRegister( state.eventSink(RecordRegisterUiEvent.OnBackButtonClick) } - ReedFullScreen( + ReedScaffold( modifier = modifier.fillMaxSize(), - ) { - ReedBackTopAppBar( - onBackClick = { - state.eventSink(RecordRegisterUiEvent.OnBackButtonClick) - }, - ) - RecordProgressBar( - currentStep = state.currentStep, - modifier = modifier.padding(horizontal = ReedTheme.spacing.spacing5), - ) - Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing10)) - when (state.currentStep) { - RecordStep.QUOTE -> { - QuoteStep(state = state) - } + topBar = { + ReedBackTopAppBar( + onBackClick = { + state.eventSink(RecordRegisterUiEvent.OnBackButtonClick) + }, + ) + }, + containerColor = White, + ) { innerPadding -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), + ) { + RecordProgressBar( + currentStep = state.currentStep, + modifier = modifier.padding(horizontal = ReedTheme.spacing.spacing5), + ) + Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing10)) + when (state.currentStep) { + RecordStep.QUOTE -> { + QuoteStep(state = state) + } - RecordStep.EMOTION -> { - EmotionStep(state = state) - } + RecordStep.EMOTION -> { + EmotionStep(state = state) + } - RecordStep.IMPRESSION -> { - ImpressionStep(state = state) + RecordStep.IMPRESSION -> { + ImpressionStep(state = state) + } } + Spacer(modifier = Modifier.weight(1f)) + ReedButton( + onClick = { + state.eventSink(RecordRegisterUiEvent.OnNextButtonClick) + }, + colorStyle = ReedButtonColorStyle.PRIMARY, + sizeStyle = largeButtonStyle, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = ReedTheme.spacing.spacing5), + enabled = state.isNextButtonEnabled, + text = stringResource(R.string.record_next_button), + multipleEventsCutterEnabled = state.currentStep == RecordStep.IMPRESSION, + ) + Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) } - Spacer(modifier = Modifier.weight(1f)) - ReedButton( - onClick = { - state.eventSink(RecordRegisterUiEvent.OnNextButtonClick) - }, - colorStyle = ReedButtonColorStyle.PRIMARY, - sizeStyle = largeButtonStyle, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = ReedTheme.spacing.spacing5), - enabled = state.isNextButtonEnabled, - text = stringResource(R.string.record_next_button), - multipleEventsCutterEnabled = state.currentStep == RecordStep.IMPRESSION, - ) - Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) } if (state.isExitDialogVisible) { diff --git a/feature/screens/build.gradle.kts b/feature/screens/build.gradle.kts index fb9f4762..cf55a687 100644 --- a/feature/screens/build.gradle.kts +++ b/feature/screens/build.gradle.kts @@ -1,5 +1,6 @@ plugins { alias(libs.plugins.booket.android.library) + alias(libs.plugins.booket.android.library.compose) alias(libs.plugins.kotlin.parcelize) } @@ -8,6 +9,14 @@ android { } dependencies { - implementation(projects.core.model) + implementations( + projects.core.designsystem, + projects.core.model, + + libs.kotlinx.collections.immutable, + + libs.circuit.foundation, + libs.compose.shadow, + ) api(libs.circuit.runtime) } diff --git a/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/Screens.kt b/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/Screens.kt index c387543d..d25439af 100644 --- a/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/Screens.kt +++ b/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/Screens.kt @@ -8,9 +8,6 @@ abstract class ReedScreen(val name: String) : Screen { override fun toString(): String = name } -@Parcelize -data object BottomNavigationScreen : ReedScreen(name = "BottomNavigation()") - @Parcelize data object HomeScreen : ReedScreen(name = "Home()") diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/component/MainBottomBar.kt b/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt similarity index 97% rename from feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/component/MainBottomBar.kt rename to feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt index fe50f72f..7599d15d 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/component/MainBottomBar.kt +++ b/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt @@ -1,4 +1,4 @@ -package com.ninecraft.booket.feature.main.component +package com.ninecraft.booket.feature.screens.component import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -30,6 +30,7 @@ import com.adamglin.composeshadow.dropShadow import com.ninecraft.booket.core.designsystem.ComponentPreview import com.ninecraft.booket.core.designsystem.theme.ReedTheme import com.ninecraft.booket.core.designsystem.theme.White +import com.ninecraft.booket.feature.screens.component.MainTab import com.slack.circuit.backstack.SaveableBackStack import com.slack.circuit.runtime.Navigator import com.slack.circuit.runtime.popUntil @@ -38,7 +39,7 @@ import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList @Composable -internal fun MainBottomBar( +fun MainBottomBar( tabs: ImmutableList, currentTab: MainTab?, onTabSelected: (MainTab) -> Unit, diff --git a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/component/MainTab.kt b/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainTab.kt similarity index 90% rename from feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/component/MainTab.kt rename to feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainTab.kt index 974d6d7a..2395c416 100644 --- a/feature/main/src/main/kotlin/com/ninecraft/booket/feature/main/component/MainTab.kt +++ b/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainTab.kt @@ -1,10 +1,10 @@ -package com.ninecraft.booket.feature.main.component +package com.ninecraft.booket.feature.screens.component import androidx.annotation.DrawableRes import androidx.annotation.StringRes -import com.ninecraft.booket.feature.main.R import com.ninecraft.booket.feature.screens.HomeScreen import com.ninecraft.booket.feature.screens.LibraryScreen +import com.ninecraft.booket.feature.screens.R import com.slack.circuit.runtime.screen.Screen enum class MainTab( diff --git a/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/extensions.kt b/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/extensions/Navigator.kt similarity index 72% rename from feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/extensions.kt rename to feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/extensions/Navigator.kt index c0cf1e0b..521365ed 100644 --- a/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/extensions.kt +++ b/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/extensions/Navigator.kt @@ -1,5 +1,6 @@ -package com.ninecraft.booket.feature.screens +package com.ninecraft.booket.feature.screens.extensions +import com.ninecraft.booket.feature.screens.ReedScreen import com.slack.circuit.runtime.Navigator import kotlinx.coroutines.delay diff --git a/feature/screens/src/main/res/drawable/ic_home.xml b/feature/screens/src/main/res/drawable/ic_home.xml new file mode 100644 index 00000000..d375aa5d --- /dev/null +++ b/feature/screens/src/main/res/drawable/ic_home.xml @@ -0,0 +1,9 @@ + + + diff --git a/feature/screens/src/main/res/drawable/ic_library.xml b/feature/screens/src/main/res/drawable/ic_library.xml new file mode 100644 index 00000000..21bfdc57 --- /dev/null +++ b/feature/screens/src/main/res/drawable/ic_library.xml @@ -0,0 +1,9 @@ + + + diff --git a/feature/screens/src/main/res/drawable/ic_selected_home.xml b/feature/screens/src/main/res/drawable/ic_selected_home.xml new file mode 100644 index 00000000..b99fb272 --- /dev/null +++ b/feature/screens/src/main/res/drawable/ic_selected_home.xml @@ -0,0 +1,9 @@ + + + diff --git a/feature/screens/src/main/res/drawable/ic_selected_library.xml b/feature/screens/src/main/res/drawable/ic_selected_library.xml new file mode 100644 index 00000000..2f02c9ac --- /dev/null +++ b/feature/screens/src/main/res/drawable/ic_selected_library.xml @@ -0,0 +1,9 @@ + + + diff --git a/feature/screens/src/main/res/values/strings.xml b/feature/screens/src/main/res/values/strings.xml new file mode 100644 index 00000000..f2b5f6f2 --- /dev/null +++ b/feature/screens/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + 내 서재 + \ No newline at end of file diff --git a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt index 0f9f2f7f..2a374f47 100644 --- a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt +++ b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt @@ -1,7 +1,6 @@ package com.ninecraft.booket.feature.search.book import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -26,14 +25,14 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.ninecraft.booket.core.common.constants.BookStatus import com.ninecraft.booket.core.designsystem.DevicePreview -import com.ninecraft.booket.core.designsystem.component.textfield.ReedTextField -import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar import com.ninecraft.booket.core.designsystem.component.ReedDivider +import com.ninecraft.booket.core.designsystem.component.textfield.ReedTextField import com.ninecraft.booket.core.designsystem.theme.ReedTheme import com.ninecraft.booket.core.designsystem.theme.White +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.core.ui.component.InfinityLazyColumn import com.ninecraft.booket.core.ui.component.LoadStateFooter -import com.ninecraft.booket.core.ui.component.ReedFullScreen +import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar import com.ninecraft.booket.feature.screens.SearchScreen import com.ninecraft.booket.feature.search.R import com.ninecraft.booket.feature.search.book.component.BookItem @@ -55,16 +54,21 @@ internal fun SearchUi( ) { HandleBookSearchSideEffects(state = state) - ReedFullScreen(modifier = modifier) { - ReedBackTopAppBar( - title = stringResource(R.string.search_title), - onBackClick = { - state.eventSink(BookSearchUiEvent.OnBackClick) - }, - ) + ReedScaffold( + modifier = modifier.fillMaxSize(), + containerColor = White, + topBar = { + ReedBackTopAppBar( + title = stringResource(R.string.search_title), + onBackClick = { + state.eventSink(BookSearchUiEvent.OnBackClick) + }, + ) + }, + ) { innerPadding -> SearchContent( state = state, - modifier = modifier, + modifier = Modifier.padding(innerPadding), ) } } @@ -80,9 +84,7 @@ internal fun SearchContent( val coroutineScope = rememberCoroutineScope() Column( - modifier = modifier - .fillMaxSize() - .background(White), + modifier = modifier.fillMaxSize(), ) { Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing3)) ReedTextField( diff --git a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt index 3ccfa9a7..052e4d10 100644 --- a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt +++ b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt @@ -1,9 +1,9 @@ package com.ninecraft.booket.feature.search.library -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -24,10 +24,10 @@ import com.ninecraft.booket.core.designsystem.component.ReedDivider import com.ninecraft.booket.core.designsystem.component.textfield.ReedTextField import com.ninecraft.booket.core.designsystem.theme.ReedTheme import com.ninecraft.booket.core.designsystem.theme.White +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.core.ui.component.InfinityLazyColumn import com.ninecraft.booket.core.ui.component.LoadStateFooter import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar -import com.ninecraft.booket.core.ui.component.ReedFullScreen import com.ninecraft.booket.feature.screens.LibrarySearchScreen import com.ninecraft.booket.feature.search.R import com.ninecraft.booket.feature.search.common.component.RecentSearchTitle @@ -44,16 +44,21 @@ internal fun LibrarySearchUi( ) { HandlingLibrarySearchSideEffect(state = state) - ReedFullScreen(modifier = modifier) { - ReedBackTopAppBar( - title = stringResource(R.string.library_search_title), - onBackClick = { - state.eventSink(LibrarySearchUiEvent.OnBackClick) - }, - ) + ReedScaffold( + modifier = modifier, + topBar = { + ReedBackTopAppBar( + title = stringResource(R.string.library_search_title), + onBackClick = { + state.eventSink(LibrarySearchUiEvent.OnBackClick) + }, + ) + }, + containerColor = White + ) { innerPadding -> LibrarySearchContent( state = state, - modifier = modifier, + innerPadding = innerPadding, ) } } @@ -61,12 +66,13 @@ internal fun LibrarySearchUi( @Composable internal fun LibrarySearchContent( state: LibrarySearchUiState, + innerPadding: PaddingValues, modifier: Modifier = Modifier, ) { Column( modifier = modifier .fillMaxSize() - .background(White), + .padding(innerPadding) ) { Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing3)) ReedTextField( diff --git a/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt b/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt index 5e0951a4..465b4973 100644 --- a/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt +++ b/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt @@ -9,7 +9,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -29,6 +28,7 @@ import com.ninecraft.booket.core.common.extensions.clickableSingle import com.ninecraft.booket.core.designsystem.DevicePreview import com.ninecraft.booket.core.ui.component.ReedDialog import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.core.designsystem.component.ReedDivider import com.ninecraft.booket.core.designsystem.theme.ReedTheme import com.ninecraft.booket.core.designsystem.theme.White @@ -57,130 +57,135 @@ internal fun SettingsUi( }.getOrNull() ?: "Unknown" } - Column( - modifier = modifier - .fillMaxSize() - .background(White) - .systemBarsPadding(), - ) { - ReedBackTopAppBar( - title = stringResource(R.string.settings_title), - onBackClick = { - state.eventSink(SettingsUiEvent.OnBackClick) - }, - ) - Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) + ReedScaffold( + modifier = modifier.fillMaxSize(), + topBar = { + ReedBackTopAppBar( + title = stringResource(R.string.settings_title), + onBackClick = { + state.eventSink(SettingsUiEvent.OnBackClick) + }, + ) + }, + containerColor = White, + ) { innerPadding -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), + ) { + Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) + SettingItem( + title = stringResource(R.string.settings_privacy_policy), + onItemClick = { + state.eventSink(SettingsUiEvent.OnPolicyClick) + }, + action = { + Icon( + imageVector = ImageVector.vectorResource(id = com.ninecraft.booket.core.designsystem.R.drawable.ic_chevron_right), + contentDescription = "Right Chevron Icon", + tint = Color.Unspecified, + ) + }, + ) + SettingItem( + title = stringResource(R.string.settings_terms_of_service), + onItemClick = { + state.eventSink(SettingsUiEvent.OnTermClick) + }, + action = { + Icon( + imageVector = ImageVector.vectorResource(id = com.ninecraft.booket.core.designsystem.R.drawable.ic_chevron_right), + contentDescription = "Right Chevron Icon", + tint = Color.Unspecified, + ) + }, + ) + SettingItem( + title = stringResource(R.string.settings_open_source_license), + onItemClick = { + state.eventSink(SettingsUiEvent.OnOssLicensesClick) + }, + action = { + Icon( + imageVector = ImageVector.vectorResource(id = com.ninecraft.booket.core.designsystem.R.drawable.ic_chevron_right), + contentDescription = "Right Chevron Icon", + tint = Color.Unspecified, + ) + }, + ) + SettingItem( + title = stringResource(R.string.settings_app_version), + isClickable = false, + action = { + Text( + text = appVersion, + style = ReedTheme.typography.body1Medium, + color = ReedTheme.colors.contentSecondary, + ) + }, + ) + ReedDivider(modifier = Modifier.padding(vertical = ReedTheme.spacing.spacing4)) + SettingItem( + title = stringResource(R.string.settings_logout), + onItemClick = { + state.eventSink(SettingsUiEvent.OnLogoutClick) + }, + ) + SettingItem( + title = stringResource(R.string.settings_withdraw), + onItemClick = { + state.eventSink(SettingsUiEvent.OnWithdrawClick) + }, + ) + } - SettingItem( - title = stringResource(R.string.settings_privacy_policy), - onItemClick = { - state.eventSink(SettingsUiEvent.OnPolicyClick) - }, - action = { - Icon( - imageVector = ImageVector.vectorResource(id = com.ninecraft.booket.core.designsystem.R.drawable.ic_chevron_right), - contentDescription = "Right Chevron Icon", - tint = Color.Unspecified, - ) - }, - ) - SettingItem( - title = stringResource(R.string.settings_terms_of_service), - onItemClick = { - state.eventSink(SettingsUiEvent.OnTermClick) - }, - action = { - Icon( - imageVector = ImageVector.vectorResource(id = com.ninecraft.booket.core.designsystem.R.drawable.ic_chevron_right), - contentDescription = "Right Chevron Icon", - tint = Color.Unspecified, - ) - }, - ) - SettingItem( - title = stringResource(R.string.settings_open_source_license), - onItemClick = { - state.eventSink(SettingsUiEvent.OnOssLicensesClick) - }, - action = { - Icon( - imageVector = ImageVector.vectorResource(id = com.ninecraft.booket.core.designsystem.R.drawable.ic_chevron_right), - contentDescription = "Right Chevron Icon", - tint = Color.Unspecified, + if (state.isLoading) { + Box( + modifier = Modifier.fillMaxSize(), + ) { + CircularProgressIndicator( + modifier = Modifier.align(Alignment.Center), + color = ReedTheme.colors.contentBrand, ) - }, - ) - SettingItem( - title = stringResource(R.string.settings_app_version), - isClickable = false, - action = { - Text( - text = appVersion, - style = ReedTheme.typography.body1Medium, - color = ReedTheme.colors.contentSecondary, - ) - }, - ) - ReedDivider(modifier = Modifier.padding(vertical = ReedTheme.spacing.spacing4)) - SettingItem( - title = stringResource(R.string.settings_logout), - onItemClick = { - state.eventSink(SettingsUiEvent.OnLogoutClick) - }, - ) - SettingItem( - title = stringResource(R.string.settings_withdraw), - onItemClick = { - state.eventSink(SettingsUiEvent.OnWithdrawClick) - }, - ) - } + } + } - if (state.isLoading) { - Box( - modifier = Modifier.fillMaxSize(), - ) { - CircularProgressIndicator( - modifier = Modifier.align(Alignment.Center), - color = ReedTheme.colors.contentBrand, + if (state.isLogoutDialogVisible) { + ReedDialog( + title = stringResource(R.string.settings_logout_title), + confirmButtonText = stringResource(R.string.settings_logout), + dismissButtonText = stringResource(R.string.settings_cancel), + onConfirmRequest = { + state.eventSink(SettingsUiEvent.Logout) + }, + onDismissRequest = { + state.eventSink(SettingsUiEvent.OnBottomSheetDismissed) + }, ) } - } - - if (state.isLogoutDialogVisible) { - ReedDialog( - title = stringResource(R.string.settings_logout_title), - confirmButtonText = stringResource(R.string.settings_logout), - dismissButtonText = stringResource(R.string.settings_cancel), - onConfirmRequest = { - state.eventSink(SettingsUiEvent.Logout) - }, - onDismissRequest = { - state.eventSink(SettingsUiEvent.OnBottomSheetDismissed) - }, - ) - } - if (state.isWithdrawBottomSheetVisible) { - WithdrawConfirmationBottomSheet( - onDismissRequest = { - state.eventSink(SettingsUiEvent.OnBottomSheetDismissed) - }, - sheetState = withDrawSheetState, - isCheckBoxChecked = state.isWithdrawConfirmed, - onCheckBoxCheckedChange = { - state.eventSink(SettingsUiEvent.OnWithdrawConfirmationToggled) - }, - onCancelButtonClick = { - coroutineScope.launch { - withDrawSheetState.hide() + if (state.isWithdrawBottomSheetVisible) { + WithdrawConfirmationBottomSheet( + onDismissRequest = { state.eventSink(SettingsUiEvent.OnBottomSheetDismissed) - } - }, - onWithdrawButtonClick = { - state.eventSink(SettingsUiEvent.Withdraw) - }, - ) + }, + sheetState = withDrawSheetState, + isCheckBoxChecked = state.isWithdrawConfirmed, + onCheckBoxCheckedChange = { + state.eventSink(SettingsUiEvent.OnWithdrawConfirmationToggled) + }, + onCancelButtonClick = { + coroutineScope.launch { + withDrawSheetState.hide() + state.eventSink(SettingsUiEvent.OnBottomSheetDismissed) + } + }, + onWithdrawButtonClick = { + state.eventSink(SettingsUiEvent.Withdraw) + }, + ) + } } } diff --git a/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt b/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt index d77621f0..3c31ff3e 100644 --- a/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt +++ b/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/osslicenses/OssLicensesUi.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn @@ -32,6 +31,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import com.ninecraft.booket.core.designsystem.DevicePreview import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar +import com.ninecraft.booket.core.ui.ReedScaffold import com.ninecraft.booket.core.designsystem.theme.ReedTheme import com.ninecraft.booket.core.designsystem.theme.White import com.ninecraft.booket.feature.settings.R @@ -59,25 +59,29 @@ internal fun OssLicenses( } } - Column( - modifier = modifier - .fillMaxSize() - .background(White) - .systemBarsPadding(), - ) { - ReedBackTopAppBar( - title = stringResource(R.string.oss_licenses_title), - onBackClick = { - state.eventSink(OssLicensesUiEvent.OnBackClicked) - }, - ) - LazyColumn { - items(licenses) { license -> - OssLicenseItem( - name = license.name, - license = license.license, - url = license.url, - ) + ReedScaffold( + modifier = modifier.fillMaxSize(), + containerColor = White, + ) { innerPadding -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), + ) { + ReedBackTopAppBar( + title = stringResource(R.string.oss_licenses_title), + onBackClick = { + state.eventSink(OssLicensesUiEvent.OnBackClicked) + }, + ) + LazyColumn { + items(licenses) { license -> + OssLicenseItem( + name = license.name, + license = license.license, + url = license.url, + ) + } } } } diff --git a/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt b/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt index 7eeb98c7..bf0c9104 100644 --- a/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt +++ b/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt @@ -5,14 +5,16 @@ import android.view.ViewGroup import android.webkit.WebView import android.webkit.WebViewClient import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.viewinterop.AndroidView import com.ninecraft.booket.core.designsystem.DevicePreview -import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar import com.ninecraft.booket.core.designsystem.theme.ReedTheme -import com.ninecraft.booket.core.ui.component.ReedFullScreen +import com.ninecraft.booket.core.ui.ReedScaffold +import com.ninecraft.booket.core.ui.component.ReedBackTopAppBar import com.ninecraft.booket.feature.screens.WebViewScreen import com.slack.circuit.codegen.annotations.CircuitInject import dagger.hilt.android.components.ActivityRetainedComponent @@ -23,16 +25,20 @@ internal fun WebViewUi( state: WebViewUiState, modifier: Modifier = Modifier, ) { - ReedFullScreen(modifier = modifier) { - ReedBackTopAppBar( - title = state.title, - onBackClick = { - state.eventSink(WebViewUiEvent.OnBackButtonClick) - }, - ) + ReedScaffold( + modifier = modifier.fillMaxSize(), + topBar = { + ReedBackTopAppBar( + title = state.title, + onBackClick = { + state.eventSink(WebViewUiEvent.OnBackButtonClick) + }, + ) + } + ) { innerPadding -> WebViewContent( state = state, - modifier = modifier, + innerPadding = innerPadding, ) } } @@ -41,9 +47,14 @@ internal fun WebViewUi( @Composable internal fun WebViewContent( state: WebViewUiState, + innerPadding: PaddingValues, modifier: Modifier = Modifier, ) { - Box(modifier = modifier.fillMaxSize()) { + Box( + modifier = modifier + .fillMaxSize() + .padding(innerPadding) + ) { AndroidView( factory = { context -> WebView(context).apply { From 80a1cecfe5aecd529e14527e83850257e7383a9e Mon Sep 17 00:00:00 2001 From: easyhooon Date: Thu, 7 Aug 2025 06:55:19 +0900 Subject: [PATCH 12/13] [BOOK-232] chore: code style check success --- .../feature/detail/record/RecordDetailUi.kt | 2 +- .../ninecraft/booket/feature/login/LoginUi.kt | 64 +++++++++---------- .../booket/feature/record/ocr/OcrUi.kt | 1 - .../register/RecordRegisterPresenter.kt | 2 +- .../screens/component/MainBottomBar.kt | 1 - .../search/book/BookSearchPresenter.kt | 2 +- .../feature/search/library/LibrarySearchUi.kt | 4 +- .../booket/feature/settings/SettingsUi.kt | 4 +- .../booket/feature/webview/WebViewUi.kt | 4 +- 9 files changed, 42 insertions(+), 42 deletions(-) diff --git a/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt b/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt index 9635444b..a3e5c199 100644 --- a/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt +++ b/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt @@ -73,7 +73,7 @@ internal fun RecordDetailUi( private fun ReviewDetailContent( state: RecordDetailUiState, innerPadding: PaddingValues, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { Column( modifier = modifier diff --git a/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginUi.kt b/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginUi.kt index 105e04a3..c55697d5 100644 --- a/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginUi.kt +++ b/feature/login/src/main/kotlin/com/ninecraft/booket/feature/login/LoginUi.kt @@ -51,44 +51,44 @@ internal fun LoginUi( verticalArrangement = Arrangement.Center, ) { Box(modifier = Modifier.fillMaxSize()) { - Text( - text = "로그인", - modifier = Modifier.align(Alignment.Center), - ) - ReedButton( - onClick = { - state.eventSink(LoginUiEvent.OnKakaoLoginButtonClick) - }, - sizeStyle = largeButtonStyle, - colorStyle = ReedButtonColorStyle.KAKAO, - modifier = Modifier - .fillMaxWidth() - .padding( - start = ReedTheme.spacing.spacing5, - end = ReedTheme.spacing.spacing5, - bottom = ReedTheme.spacing.spacing8, - ) - .align(Alignment.BottomCenter), - text = stringResource(id = R.string.kakao_login), - leadingIcon = { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_kakao), - contentDescription = "Kakao Icon", - tint = Color.Unspecified, - ) - }, - ) - - if (state.isLoading) { - CircularProgressIndicator( + Text( + text = "로그인", modifier = Modifier.align(Alignment.Center), - color = ReedTheme.colors.contentBrand, ) + ReedButton( + onClick = { + state.eventSink(LoginUiEvent.OnKakaoLoginButtonClick) + }, + sizeStyle = largeButtonStyle, + colorStyle = ReedButtonColorStyle.KAKAO, + modifier = Modifier + .fillMaxWidth() + .padding( + start = ReedTheme.spacing.spacing5, + end = ReedTheme.spacing.spacing5, + bottom = ReedTheme.spacing.spacing8, + ) + .align(Alignment.BottomCenter), + text = stringResource(id = R.string.kakao_login), + leadingIcon = { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_kakao), + contentDescription = "Kakao Icon", + tint = Color.Unspecified, + ) + }, + ) + + if (state.isLoading) { + CircularProgressIndicator( + modifier = Modifier.align(Alignment.Center), + color = ReedTheme.colors.contentBrand, + ) + } } } } } -} @DevicePreview @Composable diff --git a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt index 2f3f5127..33e61926 100644 --- a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt +++ b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt @@ -113,7 +113,6 @@ private fun CameraPreview( } } - LaunchedEffect(Unit) { val granted = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED if (granted) { diff --git a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterPresenter.kt b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterPresenter.kt index c646d6c0..9c7dc634 100644 --- a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterPresenter.kt +++ b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterPresenter.kt @@ -18,7 +18,7 @@ import com.ninecraft.booket.feature.screens.LoginScreen import com.ninecraft.booket.feature.screens.OcrScreen import com.ninecraft.booket.feature.screens.RecordDetailScreen import com.ninecraft.booket.feature.screens.RecordScreen -import com.ninecraft.booket.feature.screens.delayedPop +import com.ninecraft.booket.feature.screens.extensions.delayedPop import com.orhanobut.logger.Logger import com.slack.circuit.codegen.annotations.CircuitInject import com.slack.circuit.foundation.rememberAnsweringNavigator diff --git a/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt b/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt index 7599d15d..a23c9bcb 100644 --- a/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt +++ b/feature/screens/src/main/kotlin/com/ninecraft/booket/feature/screens/component/MainBottomBar.kt @@ -30,7 +30,6 @@ import com.adamglin.composeshadow.dropShadow import com.ninecraft.booket.core.designsystem.ComponentPreview import com.ninecraft.booket.core.designsystem.theme.ReedTheme import com.ninecraft.booket.core.designsystem.theme.White -import com.ninecraft.booket.feature.screens.component.MainTab import com.slack.circuit.backstack.SaveableBackStack import com.slack.circuit.runtime.Navigator import com.slack.circuit.runtime.popUntil diff --git a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt index 14d5c2c3..4ba016d9 100644 --- a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt +++ b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchPresenter.kt @@ -17,7 +17,7 @@ import com.ninecraft.booket.core.ui.component.FooterState import com.ninecraft.booket.feature.screens.LoginScreen import com.ninecraft.booket.feature.screens.RecordScreen import com.ninecraft.booket.feature.screens.SearchScreen -import com.ninecraft.booket.feature.screens.delayedGoTo +import com.ninecraft.booket.feature.screens.extensions.delayedGoTo import com.orhanobut.logger.Logger import com.slack.circuit.codegen.annotations.CircuitInject import com.slack.circuit.retained.collectAsRetainedState diff --git a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt index 052e4d10..1c92cb5f 100644 --- a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt +++ b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt @@ -54,7 +54,7 @@ internal fun LibrarySearchUi( }, ) }, - containerColor = White + containerColor = White, ) { innerPadding -> LibrarySearchContent( state = state, @@ -72,7 +72,7 @@ internal fun LibrarySearchContent( Column( modifier = modifier .fillMaxSize() - .padding(innerPadding) + .padding(innerPadding), ) { Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing3)) ReedTextField( diff --git a/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt b/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt index 465b4973..a3af654c 100644 --- a/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt +++ b/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt @@ -58,7 +58,9 @@ internal fun SettingsUi( } ReedScaffold( - modifier = modifier.fillMaxSize(), + modifier = modifier + .fillMaxSize() + .background(White), topBar = { ReedBackTopAppBar( title = stringResource(R.string.settings_title), diff --git a/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt b/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt index bf0c9104..d4badad7 100644 --- a/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt +++ b/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt @@ -34,7 +34,7 @@ internal fun WebViewUi( state.eventSink(WebViewUiEvent.OnBackButtonClick) }, ) - } + }, ) { innerPadding -> WebViewContent( state = state, @@ -53,7 +53,7 @@ internal fun WebViewContent( Box( modifier = modifier .fillMaxSize() - .padding(innerPadding) + .padding(innerPadding), ) { AndroidView( factory = { context -> From 7a19efb87ed2d2156b15561514c46ab38e86a2b5 Mon Sep 17 00:00:00 2001 From: easyhooon Date: Thu, 7 Aug 2025 10:27:37 +0900 Subject: [PATCH 13/13] =?UTF-8?q?[BOOK-232]=20refactor:=20=EB=B0=94?= =?UTF-8?q?=ED=85=80=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4=EC=85=98=EC=9D=B4?= =?UTF-8?q?=20=EC=97=86=EB=8A=94=20=ED=99=94=EB=A9=B4=EB=93=A4=20statusBar?= =?UTF-8?q?Padding=20=EB=8C=80=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scaffold topBar 슬롯에 topBar를 배치하는 경우 modifier를 통한 추가적인 padding을 적용해야하므로 topBar 까지 content 영역으로 이동 systemUiController 의존성 필요없는 모듈 의존성 제거 --- .../feature/detail/book/BookDetailUi.kt | 14 +++--- .../feature/detail/record/RecordDetailUi.kt | 18 ++++--- feature/home/build.gradle.kts | 2 - feature/library/build.gradle.kts | 2 - .../booket/feature/record/ocr/OcrUi.kt | 48 ++++++++++++------- .../record/register/RecordRegisterUi.kt | 12 ++--- .../feature/search/book/BookSearchUi.kt | 18 ++++--- .../feature/search/library/LibrarySearchUi.kt | 14 +++--- .../booket/feature/settings/SettingsUi.kt | 14 +++--- .../booket/feature/webview/WebViewUi.kt | 18 ++++--- 10 files changed, 81 insertions(+), 79 deletions(-) diff --git a/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt b/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt index 861b6f47..45b8a6d0 100644 --- a/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt +++ b/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/book/BookDetailUi.kt @@ -68,14 +68,6 @@ internal fun BookDetailUi( ReedScaffold( modifier = modifier.fillMaxSize(), - topBar = { - ReedBackTopAppBar( - title = "", - onBackClick = { - state.eventSink(BookDetailUiEvent.OnBackClick) - }, - ) - }, ) { innerPadding -> BookDetailContent( state = state, @@ -139,6 +131,12 @@ internal fun BookDetailContent( .padding(innerPadding) .verticalScroll(rememberScrollState()), ) { + ReedBackTopAppBar( + title = "", + onBackClick = { + state.eventSink(BookDetailUiEvent.OnBackClick) + }, + ) Row( modifier = modifier .fillMaxWidth() diff --git a/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt b/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt index a3e5c199..dfe228bb 100644 --- a/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt +++ b/feature/detail/src/main/kotlin/com/ninecraft/booket/feature/detail/record/RecordDetailUi.kt @@ -50,16 +50,6 @@ internal fun RecordDetailUi( ReedScaffold( modifier = modifier.fillMaxSize(), - topBar = { - ReedTopAppBar( - title = stringResource(R.string.review_detail_title), - startIconRes = designR.drawable.ic_close, - startIconDescription = "Close Icon", - startIconOnClick = { - state.eventSink(RecordDetailUiEvent.OnCloseClicked) - }, - ) - }, containerColor = White, ) { innerPadding -> ReviewDetailContent( @@ -80,6 +70,14 @@ private fun ReviewDetailContent( .fillMaxSize() .padding(innerPadding), ) { + ReedTopAppBar( + title = stringResource(R.string.review_detail_title), + startIconRes = designR.drawable.ic_close, + startIconDescription = "Close Icon", + startIconOnClick = { + state.eventSink(RecordDetailUiEvent.OnCloseClicked) + }, + ) Row( modifier = modifier .fillMaxWidth() diff --git a/feature/home/build.gradle.kts b/feature/home/build.gradle.kts index 55ce76d4..0f7b8d5e 100644 --- a/feature/home/build.gradle.kts +++ b/feature/home/build.gradle.kts @@ -17,7 +17,5 @@ ksp { dependencies { implementations( libs.logger, - - libs.compose.system.ui.controller, ) } diff --git a/feature/library/build.gradle.kts b/feature/library/build.gradle.kts index 90fafaff..5f01e5ca 100644 --- a/feature/library/build.gradle.kts +++ b/feature/library/build.gradle.kts @@ -17,7 +17,5 @@ ksp { dependencies { implementations( libs.logger, - - libs.compose.system.ui.controller, ) } diff --git a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt index 33e61926..4dcf88de 100644 --- a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt +++ b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/ocr/OcrUi.kt @@ -63,6 +63,7 @@ import com.ninecraft.booket.feature.record.ocr.component.SentenceBox import com.ninecraft.booket.feature.screens.OcrScreen import com.slack.circuit.codegen.annotations.CircuitInject import dagger.hilt.android.components.ActivityRetainedComponent +import tech.thdev.compose.exteions.system.ui.controller.rememberSystemUiController import com.ninecraft.booket.core.designsystem.R as designR @CircuitInject(OcrScreen::class, ActivityRetainedComponent::class) @@ -113,6 +114,24 @@ private fun CameraPreview( } } + val systemUiController = rememberSystemUiController() + + DisposableEffect(systemUiController) { + systemUiController.setSystemBarsColor( + color = Color.Transparent, + darkIcons = false, + isNavigationBarContrastEnforced = false, + ) + + onDispose { + systemUiController.setSystemBarsColor( + color = Color.Transparent, + darkIcons = true, + isNavigationBarContrastEnforced = false, + ) + } + } + LaunchedEffect(Unit) { val granted = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED if (granted) { @@ -137,15 +156,6 @@ private fun CameraPreview( ReedScaffold( modifier = modifier.fillMaxSize(), containerColor = Neutral950, - topBar = { - ReedCloseTopAppBar( - modifier = Modifier.background(color = Color.Black), - isDark = true, - onClose = { - state.eventSink(OcrUiEvent.OnCloseClick) - }, - ) - }, ) { innerPadding -> Box( modifier = Modifier @@ -156,6 +166,12 @@ private fun CameraPreview( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { + ReedCloseTopAppBar( + isDark = true, + onClose = { + state.eventSink(OcrUiEvent.OnCloseClick) + }, + ) Text( text = stringResource(R.string.ocr_guide), color = ReedTheme.colors.contentInverse, @@ -251,20 +267,18 @@ private fun TextScanResult( ReedScaffold( modifier = modifier.fillMaxSize(), containerColor = White, - topBar = { - ReedCloseTopAppBar( - title = stringResource(R.string.ocr_sentence_selection), - onClose = { - state.eventSink(OcrUiEvent.OnCloseClick) - }, - ) - }, ) { innerPadding -> Column( modifier = Modifier .fillMaxSize() .padding(innerPadding), ) { + ReedCloseTopAppBar( + title = stringResource(R.string.ocr_sentence_selection), + onClose = { + state.eventSink(OcrUiEvent.OnCloseClick) + }, + ) LazyColumn( modifier = Modifier .weight(1f) diff --git a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt index 24eb3b7b..6d3ce3f4 100644 --- a/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt +++ b/feature/record/src/main/kotlin/com/ninecraft/booket/feature/record/register/RecordRegisterUi.kt @@ -47,13 +47,6 @@ internal fun RecordRegister( ReedScaffold( modifier = modifier.fillMaxSize(), - topBar = { - ReedBackTopAppBar( - onBackClick = { - state.eventSink(RecordRegisterUiEvent.OnBackButtonClick) - }, - ) - }, containerColor = White, ) { innerPadding -> Column( @@ -61,6 +54,11 @@ internal fun RecordRegister( .fillMaxSize() .padding(innerPadding), ) { + ReedBackTopAppBar( + onBackClick = { + state.eventSink(RecordRegisterUiEvent.OnBackButtonClick) + }, + ) RecordProgressBar( currentStep = state.currentStep, modifier = modifier.padding(horizontal = ReedTheme.spacing.spacing5), diff --git a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt index 2a374f47..9b48220d 100644 --- a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt +++ b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/book/BookSearchUi.kt @@ -57,19 +57,23 @@ internal fun SearchUi( ReedScaffold( modifier = modifier.fillMaxSize(), containerColor = White, - topBar = { + ) { innerPadding -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), + ) { ReedBackTopAppBar( title = stringResource(R.string.search_title), onBackClick = { state.eventSink(BookSearchUiEvent.OnBackClick) }, ) - }, - ) { innerPadding -> - SearchContent( - state = state, - modifier = Modifier.padding(innerPadding), - ) + SearchContent( + state = state, + modifier = Modifier, + ) + } } } diff --git a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt index 1c92cb5f..d4e29d1e 100644 --- a/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt +++ b/feature/search/src/main/kotlin/com/ninecraft/booket/feature/search/library/LibrarySearchUi.kt @@ -46,14 +46,6 @@ internal fun LibrarySearchUi( ReedScaffold( modifier = modifier, - topBar = { - ReedBackTopAppBar( - title = stringResource(R.string.library_search_title), - onBackClick = { - state.eventSink(LibrarySearchUiEvent.OnBackClick) - }, - ) - }, containerColor = White, ) { innerPadding -> LibrarySearchContent( @@ -74,6 +66,12 @@ internal fun LibrarySearchContent( .fillMaxSize() .padding(innerPadding), ) { + ReedBackTopAppBar( + title = stringResource(R.string.library_search_title), + onBackClick = { + state.eventSink(LibrarySearchUiEvent.OnBackClick) + }, + ) Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing3)) ReedTextField( queryState = state.queryState, diff --git a/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt b/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt index a3af654c..a81185c8 100644 --- a/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt +++ b/feature/settings/src/main/kotlin/com/ninecraft/booket/feature/settings/SettingsUi.kt @@ -61,14 +61,6 @@ internal fun SettingsUi( modifier = modifier .fillMaxSize() .background(White), - topBar = { - ReedBackTopAppBar( - title = stringResource(R.string.settings_title), - onBackClick = { - state.eventSink(SettingsUiEvent.OnBackClick) - }, - ) - }, containerColor = White, ) { innerPadding -> Column( @@ -76,6 +68,12 @@ internal fun SettingsUi( .fillMaxSize() .padding(innerPadding), ) { + ReedBackTopAppBar( + title = stringResource(R.string.settings_title), + onBackClick = { + state.eventSink(SettingsUiEvent.OnBackClick) + }, + ) Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing4)) SettingItem( title = stringResource(R.string.settings_privacy_policy), diff --git a/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt b/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt index d4badad7..4835072d 100644 --- a/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt +++ b/feature/webview/src/main/kotlin/com/ninecraft/booket/feature/webview/WebViewUi.kt @@ -4,7 +4,7 @@ import android.annotation.SuppressLint import android.view.ViewGroup import android.webkit.WebView import android.webkit.WebViewClient -import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -27,14 +27,6 @@ internal fun WebViewUi( ) { ReedScaffold( modifier = modifier.fillMaxSize(), - topBar = { - ReedBackTopAppBar( - title = state.title, - onBackClick = { - state.eventSink(WebViewUiEvent.OnBackButtonClick) - }, - ) - }, ) { innerPadding -> WebViewContent( state = state, @@ -50,11 +42,17 @@ internal fun WebViewContent( innerPadding: PaddingValues, modifier: Modifier = Modifier, ) { - Box( + Column( modifier = modifier .fillMaxSize() .padding(innerPadding), ) { + ReedBackTopAppBar( + title = state.title, + onBackClick = { + state.eventSink(WebViewUiEvent.OnBackButtonClick) + }, + ) AndroidView( factory = { context -> WebView(context).apply {