Skip to content

Commit e8ae3a1

Browse files
authored
Merge pull request #92 from YAPP-Github/feature/jaino/#91
#91 : 쪽지 로띠 적용 및 로딩 에니메이션 적용
2 parents dff12dd + 7051ab2 commit e8ae3a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+269
-166
lines changed

app/src/main/kotlin/com/bff/wespot/AppNavGraphs.kt

+20-12
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,20 @@ import androidx.navigation.NavGraph
1515
import androidx.navigation.NavHostController
1616
import com.bff.wespot.entire.screen.screen.destinations.AccountSettingScreenDestination
1717
import com.bff.wespot.entire.screen.screen.destinations.BlockListScreenDestination
18-
import com.bff.wespot.entire.screen.screen.destinations.CharacterEditScreenDestination
1918
import com.bff.wespot.entire.screen.screen.destinations.EntireScreenDestination
2019
import com.bff.wespot.entire.screen.screen.destinations.NotificationSettingScreenDestination
21-
import com.bff.wespot.entire.screen.screen.destinations.ProfileEditScreenDestination
2220
import com.bff.wespot.entire.screen.screen.destinations.RevokeConfirmScreenDestination
2321
import com.bff.wespot.entire.screen.screen.destinations.RevokeScreenDestination
2422
import com.bff.wespot.entire.screen.screen.destinations.SettingScreenDestination
23+
import com.bff.wespot.entire.screen.screen.destinations.ProfileEditScreenDestination
24+
import com.bff.wespot.entire.screen.screen.destinations.CharacterEditScreenDestination
2525
import com.bff.wespot.message.screen.destinations.MessageEditScreenDestination
2626
import com.bff.wespot.message.screen.destinations.MessageScreenDestination
2727
import com.bff.wespot.message.screen.destinations.MessageWriteScreenDestination
2828
import com.bff.wespot.message.screen.destinations.ReceiverSelectionScreenDestination
2929
import com.bff.wespot.message.screen.destinations.ReservedMessageScreenDestination
3030
import com.bff.wespot.message.viewmodel.SendViewModel
31+
import com.bff.wespot.model.ToastState
3132
import com.bff.wespot.notification.screen.destinations.NotificationScreenDestination
3233
import com.bff.wespot.navigation.Navigator
3334
import com.bff.wespot.vote.screen.destinations.CharacterSettingScreenDestination
@@ -126,7 +127,13 @@ object AppNavGraphs {
126127
}
127128
}
128129

129-
private val tabScreenNames = listOf(
130+
private val bottomBarScreenNames = listOf(
131+
"vote/vote_home_screen",
132+
"message/message_screen?isMessageSent={isMessageSent}",
133+
"entire/entire_screen",
134+
)
135+
136+
private val topBarScreenNames = listOf(
130137
"vote/vote_home_screen",
131138
"message/message_screen?isMessageSent={isMessageSent}&type={type}&messageId={messageId}",
132139
)
@@ -143,15 +150,15 @@ fun NavDestination.navGraph(): NavGraphSpec {
143150
throw ClassNotFoundException("Unknown nav graph for destination $route")
144151
}
145152

146-
fun NavDestination.checkDestination(): Boolean {
147-
hierarchy.forEach { destination ->
148-
tabScreenNames.forEach { name ->
149-
if (destination.route == name) {
150-
return true
151-
}
152-
}
153+
internal fun NavDestination.checkDestination(position: NavigationBarPosition): Boolean {
154+
val screenNames = when (position) {
155+
NavigationBarPosition.BOTTOM -> bottomBarScreenNames
156+
NavigationBarPosition.TOP -> topBarScreenNames
157+
}
158+
159+
return hierarchy.any { destination ->
160+
screenNames.any { name -> destination.route == name }
153161
}
154-
return false
155162
}
156163

157164
fun DestinationScopeWithNoDependencies<*>.currentNavigator(): CommonNavGraphNavigator {
@@ -165,6 +172,7 @@ fun DestinationScopeWithNoDependencies<*>.currentNavigator(): CommonNavGraphNavi
165172
internal fun AppNavigation(
166173
navController: NavHostController,
167174
modifier: Modifier = Modifier,
175+
showToast: (ToastState) -> Unit,
168176
navigator: Navigator,
169177
) {
170178
val engine = rememberNavHostEngine(
@@ -187,7 +195,7 @@ internal fun AppNavigation(
187195
dependency(navigator)
188196
dependency(sendViewModel)
189197
dependency(votingViewModel)
190-
dependency(navigator)
198+
dependency(showToast)
191199
},
192200
)
193201
}

app/src/main/kotlin/com/bff/wespot/MainActivity.kt

+25-6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import androidx.compose.runtime.State
2929
import androidx.compose.runtime.getValue
3030
import androidx.compose.runtime.mutableStateOf
3131
import androidx.compose.runtime.remember
32+
import androidx.compose.runtime.setValue
3233
import androidx.compose.ui.Alignment
3334
import androidx.compose.ui.Modifier
3435
import androidx.compose.ui.graphics.painter.Painter
@@ -43,9 +44,11 @@ import androidx.navigation.compose.rememberNavController
4344
import com.ramcosta.composedestinations.dynamic.within
4445
import com.bff.wespot.designsystem.R
4546
import com.bff.wespot.designsystem.component.header.WSTopBar
47+
import com.bff.wespot.designsystem.component.indicator.WSToast
4648
import com.bff.wespot.designsystem.theme.StaticTypeScale
4749
import com.bff.wespot.designsystem.theme.WeSpotTheme
4850
import com.bff.wespot.designsystem.theme.WeSpotThemeManager
51+
import com.bff.wespot.model.ToastState
4952
import com.bff.wespot.message.screen.MessageScreenArgs
5053
import com.bff.wespot.message.screen.destinations.MessageScreenDestination
5154
import com.bff.wespot.message.screen.destinations.ReceiverSelectionScreenDestination
@@ -118,13 +121,15 @@ data class MainScreenNavArgs(
118121
@Composable
119122
private fun MainScreen(navigator: Navigator, navArgs: MainScreenNavArgs) {
120123
val navController = rememberNavController()
124+
var toast by remember { mutableStateOf(ToastState()) }
121125

122-
val checkScreen by navController.checkCurrentScreen()
126+
val isTopNavigationScreen by navController.checkCurrentScreen(NavigationBarPosition.TOP)
127+
val isBottomNavigationScreen by navController.checkCurrentScreen(NavigationBarPosition.BOTTOM)
123128

124129
Scaffold(
125130
modifier = Modifier.fillMaxSize(),
126131
topBar = {
127-
if (checkScreen) {
132+
if (isTopNavigationScreen) {
128133
WSTopBar(
129134
title = "",
130135
navigation = {
@@ -157,7 +162,7 @@ private fun MainScreen(navigator: Navigator, navArgs: MainScreenNavArgs) {
157162
}
158163
},
159164
bottomBar = {
160-
if (checkScreen) {
165+
if (isBottomNavigationScreen) {
161166
val currentSelectedItem by navController.currentScreenAsState()
162167
BottomNavigationTab(
163168
selectedNavigation = currentSelectedItem,
@@ -172,11 +177,25 @@ private fun MainScreen(navigator: Navigator, navArgs: MainScreenNavArgs) {
172177
AppNavigation(
173178
navController = navController,
174179
modifier = Modifier.padding(it),
175-
navigator = navigator
180+
navigator = navigator,
181+
showToast = { toastState -> toast = toastState }
176182
)
177183

178184
navigateScreenFromNavArgs(navArgs, navController)
179185
}
186+
187+
if (toast.show) {
188+
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.TopCenter) {
189+
WSToast(
190+
text = stringResource(toast.message),
191+
showToast = toast.show,
192+
toastType = toast.type,
193+
closeToast = {
194+
toast = toast.copy(show = false)
195+
},
196+
)
197+
}
198+
}
180199
}
181200

182201
@Composable
@@ -230,12 +249,12 @@ private fun NavController.currentScreenAsState(): State<NavGraphSpec> {
230249

231250
@Stable
232251
@Composable
233-
private fun NavController.checkCurrentScreen(): State<Boolean> {
252+
private fun NavController.checkCurrentScreen(position: NavigationBarPosition): State<Boolean> {
234253
val showBar = remember { mutableStateOf(false) }
235254

236255
DisposableEffect(this) {
237256
val listener = NavController.OnDestinationChangedListener { _, destination, _ ->
238-
showBar.value = destination.checkDestination()
257+
showBar.value = destination.checkDestination(position)
239258
}
240259

241260
addOnDestinationChangedListener(listener)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.bff.wespot
2+
3+
internal enum class NavigationBarPosition {
4+
BOTTOM, TOP,
5+
}

core/ui/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ dependencies {
1818
implementation(libs.coil.core)
1919
implementation(libs.coil.compose)
2020
implementation(libs.timber)
21+
implementation(libs.lottie)
2122
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.bff.wespot.ui
2+
3+
import androidx.compose.foundation.clickable
4+
import androidx.compose.foundation.layout.Box
5+
import androidx.compose.foundation.layout.fillMaxSize
6+
import androidx.compose.foundation.layout.size
7+
import androidx.compose.runtime.Composable
8+
import androidx.compose.runtime.getValue
9+
import androidx.compose.ui.Alignment
10+
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.unit.dp
12+
import com.airbnb.lottie.compose.LottieAnimation
13+
import com.airbnb.lottie.compose.LottieCompositionSpec
14+
import com.airbnb.lottie.compose.LottieConstants
15+
import com.airbnb.lottie.compose.rememberLottieComposition
16+
17+
@Composable
18+
fun LoadingAnimation(isBackgroundClicked: Boolean = false) {
19+
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.loading))
20+
21+
Box(
22+
modifier = Modifier
23+
.clickable(enabled = isBackgroundClicked) { }
24+
.fillMaxSize(),
25+
contentAlignment = Alignment.Center,
26+
) {
27+
LottieAnimation(
28+
modifier = Modifier.size(80.dp),
29+
composition = composition,
30+
iterations = LottieConstants.IterateForever,
31+
)
32+
}
33+
}

core/ui/src/main/res/raw/loading.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"v":"4.8.0","meta":{"g":"LottieFiles AE 3.5.9","a":"","k":"","d":"","tc":""},"fr":30,"ip":0,"op":59,"w":800,"h":800,"nm":"4.로딩","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Layer 1 Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[90]},{"t":60,"s":[450]}],"ix":10},"p":{"a":0,"k":[400,400,0],"ix":2},"a":{"a":0,"k":[482.723,482.723,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,128.529],[-128.53,0],[0,-128.529],[128.529,0]],"o":[[0,-128.529],[128.529,0],[0,128.529],[-128.53,0]],"v":[[-232.723,0],[0.001,-232.723],[232.723,0],[0.001,232.723]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.898846794577,0.926102941176,0.534296671549,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":100,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[482.723,482.723],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":23,"s":[0]},{"t":60,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":35,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":59,"st":0,"bm":0}],"markers":[]}

feature/entire/src/main/java/com/bff/wespot/entire/screen/screen/EntireScreen.kt feature/entire/src/main/java/com/bff/wespot/entire/screen/EntireScreen.kt

-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ import com.ramcosta.composedestinations.annotation.Destination
5252
import org.orbitmvi.orbit.compose.collectAsState
5353

5454
interface EntireNavigator {
55-
fun navigateUp()
5655
fun navigateToSetting()
5756
fun navigateToProfileEditScreen(args: ProfileEditNavArgs)
5857
}
@@ -71,8 +70,6 @@ internal fun EntireScreen(
7170
topBar = {
7271
WSTopBar(
7372
title = "",
74-
canNavigateBack = true,
75-
navigateUp = { navigator.navigateUp() },
7673
action = {
7774
Icon(
7875
modifier = Modifier

feature/entire/src/main/java/com/bff/wespot/entire/screen/screen/edit/CharacterEditScreen.kt feature/entire/src/main/java/com/bff/wespot/entire/screen/edit/CharacterEditScreen.kt

+3-15
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
package com.bff.wespot.entire.screen.screen.edit
22

3-
import androidx.compose.foundation.clickable
43
import androidx.compose.foundation.layout.Box
5-
import androidx.compose.foundation.layout.fillMaxSize
64
import androidx.compose.foundation.layout.padding
7-
import androidx.compose.material3.CircularProgressIndicator
85
import androidx.compose.material3.ExperimentalMaterial3Api
96
import androidx.compose.material3.Scaffold
107
import androidx.compose.runtime.Composable
118
import androidx.compose.runtime.LaunchedEffect
129
import androidx.compose.runtime.getValue
13-
import androidx.compose.ui.Alignment
1410
import androidx.compose.ui.Modifier
1511
import androidx.hilt.navigation.compose.hiltViewModel
1612
import com.bff.wespot.designsystem.component.header.WSTopBar
@@ -19,6 +15,7 @@ import com.bff.wespot.entire.screen.state.edit.EntireEditSideEffect
1915
import com.bff.wespot.entire.screen.viewmodel.EntireEditViewModel
2016
import com.bff.wespot.model.user.response.ProfileCharacter
2117
import com.bff.wespot.ui.CharacterScreen
18+
import com.bff.wespot.ui.LoadingAnimation
2219
import com.ramcosta.composedestinations.annotation.Destination
2320
import org.orbitmvi.orbit.compose.collectAsState
2421
import org.orbitmvi.orbit.compose.collectSideEffect
@@ -57,9 +54,7 @@ fun CharacterEditScreen(
5754
state.backgroundColorList.isEmpty() ||
5855
state.profile.name.isEmpty()
5956
) {
60-
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
61-
CircularProgressIndicator()
62-
}
57+
LoadingAnimation()
6358
return
6459
}
6560

@@ -89,13 +84,6 @@ fun CharacterEditScreen(
8984
}
9085

9186
if (state.isLoading) {
92-
Box(
93-
modifier = Modifier
94-
.fillMaxSize()
95-
.clickable(enabled = false) { },
96-
contentAlignment = Alignment.Center,
97-
) {
98-
CircularProgressIndicator()
99-
}
87+
LoadingAnimation()
10088
}
10189
}

feature/entire/src/main/java/com/bff/wespot/entire/screen/screen/edit/ProfileEditScreen.kt feature/entire/src/main/java/com/bff/wespot/entire/screen/edit/ProfileEditScreen.kt

+2-9
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import androidx.compose.foundation.layout.size
1616
import androidx.compose.foundation.rememberScrollState
1717
import androidx.compose.foundation.shape.CircleShape
1818
import androidx.compose.foundation.verticalScroll
19-
import androidx.compose.material3.CircularProgressIndicator
2019
import androidx.compose.material3.ExperimentalMaterial3Api
2120
import androidx.compose.material3.Scaffold
2221
import androidx.compose.material3.Text
@@ -55,6 +54,7 @@ import com.bff.wespot.entire.screen.state.edit.EntireEditSideEffect
5554
import com.bff.wespot.entire.screen.viewmodel.EntireEditViewModel
5655
import com.bff.wespot.model.ToastState
5756
import com.bff.wespot.ui.LetterCountIndicator
57+
import com.bff.wespot.ui.LoadingAnimation
5858
import com.bff.wespot.util.hexToColor
5959
import com.ramcosta.composedestinations.annotation.Destination
6060
import kotlinx.coroutines.delay
@@ -240,14 +240,7 @@ fun ProfileEditScreen(
240240
}
241241

242242
if (state.isLoading) {
243-
Box(
244-
modifier = Modifier
245-
.fillMaxSize()
246-
.clickable(enabled = false) { },
247-
contentAlignment = Alignment.Center,
248-
) {
249-
CircularProgressIndicator()
250-
}
243+
LoadingAnimation()
251244
}
252245

253246
LaunchedEffect(Unit) {

feature/entire/src/main/java/com/bff/wespot/entire/screen/screen/setting/BlockListScreen.kt feature/entire/src/main/java/com/bff/wespot/entire/screen/setting/BlockListScreen.kt

+2-13
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
package com.bff.wespot.entire.screen.screen.setting
22

3-
import androidx.compose.foundation.clickable
43
import androidx.compose.foundation.layout.Arrangement
5-
import androidx.compose.foundation.layout.Box
64
import androidx.compose.foundation.layout.Column
7-
import androidx.compose.foundation.layout.fillMaxSize
85
import androidx.compose.foundation.layout.padding
96
import androidx.compose.foundation.lazy.LazyColumn
107
import androidx.compose.foundation.lazy.items
11-
import androidx.compose.material3.CircularProgressIndicator
128
import androidx.compose.material3.ExperimentalMaterial3Api
139
import androidx.compose.material3.Scaffold
1410
import androidx.compose.material3.Text
@@ -18,7 +14,6 @@ import androidx.compose.runtime.getValue
1814
import androidx.compose.runtime.mutableStateOf
1915
import androidx.compose.runtime.remember
2016
import androidx.compose.runtime.setValue
21-
import androidx.compose.ui.Alignment
2217
import androidx.compose.ui.Modifier
2318
import androidx.compose.ui.res.stringResource
2419
import androidx.compose.ui.unit.dp
@@ -30,6 +25,7 @@ import com.bff.wespot.designsystem.theme.WeSpotThemeManager
3025
import com.bff.wespot.entire.R
3126
import com.bff.wespot.entire.screen.state.EntireAction
3227
import com.bff.wespot.entire.screen.viewmodel.EntireViewModel
28+
import com.bff.wespot.ui.LoadingAnimation
3329
import com.bff.wespot.ui.ReservedMessageItem
3430
import com.ramcosta.composedestinations.annotation.Destination
3531
import org.orbitmvi.orbit.compose.collectAsState
@@ -105,14 +101,7 @@ fun BlockListScreen(
105101
}
106102

107103
if (state.isLoading) {
108-
Box(
109-
modifier = Modifier
110-
.fillMaxSize()
111-
.clickable(enabled = false) { },
112-
contentAlignment = Alignment.Center,
113-
) {
114-
CircularProgressIndicator()
115-
}
104+
LoadingAnimation()
116105
}
117106

118107
LaunchedEffect(Unit) {

feature/message/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dependencies {
1818
implementation(libs.bundles.orbit)
1919
implementation(libs.junit)
2020
implementation(libs.androidx.junit)
21+
implementation(libs.lottie)
2122
implementation(libs.coil.core)
2223
implementation(libs.coil.compose)
2324
}

0 commit comments

Comments
 (0)