Skip to content

Commit

Permalink
Merge pull request #70 from Team-Wable/feature/#66-splash
Browse files Browse the repository at this point in the history
[Feature/#66] splash 로띠
  • Loading branch information
chanubc authored Sep 5, 2024
2 parents 9fa236a + 5995cc6 commit b203125
Show file tree
Hide file tree
Showing 17 changed files with 156 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal class DefaultPostingRepository @Inject constructor(
override suspend fun postingMultiPart(title: String, content: String, uriImage: String?): Result<Unit> {
return runCatching {
val textRequestBody = createContentRequestBody(title, content)
val imagePart = contentResolver.createImagePart(uriImage)
val imagePart = contentResolver.createImagePart(uriImage, FILE_NAME)

postingService.postingMultiPart(textRequestBody, imagePart)
Unit
Expand All @@ -32,4 +32,8 @@ internal class DefaultPostingRepository @Inject constructor(
}.toString()
return contentJson.toRequestBody("application/json".toMediaTypeOrNull())
}

companion object {
private const val FILE_NAME = "image"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ internal class DefaultProfileRepository @Inject constructor(

override suspend fun patchUserProfile(info: MemberInfoEditModel, imgUrl: String?): Result<Unit> = runCatching {
val infoRequestBody = createContentRequestBody(info)
val filePart = contentResolver.createImagePart(imgUrl)
val filePart = contentResolver.createImagePart(imgUrl, FILE_NAME)

apiService.patchUserProfile(infoRequestBody, filePart)
Unit
Expand Down Expand Up @@ -75,4 +75,8 @@ internal class DefaultProfileRepository @Inject constructor(
}.onFailure {
return it.handleThrowable()
}

companion object {
private const val FILE_NAME = "file"
}
}
1 change: 1 addition & 0 deletions core/network/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ dependencies {
implementation(project(":core:datastore"))
implementation(libs.androidx.exifinterface)
implementation(libs.paging)
implementation(libs.process.phoenix)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.teamwable.network

import android.app.Application
import android.content.Intent
import android.widget.Toast
import com.jakewharton.processphoenix.ProcessPhoenix
import com.teamwable.datastore.datasource.DefaultWablePreferenceDatasource
import com.teamwable.network.datasource.AuthService
import com.teamwable.network.util.UNKNOWN_ERROR_MESSAGE
Expand All @@ -14,6 +14,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
Expand Down Expand Up @@ -74,14 +75,12 @@ class TokenInterceptor @Inject constructor(
}
}

private fun handleFailedTokenReissue() = with(context) {
private fun handleFailedTokenReissue() {
CoroutineScope(Dispatchers.Main).launch {
defaultWablePreferenceDatasource.clear()
startActivity(
Intent.makeRestartActivityTask(
packageManager.getLaunchIntentForPackage(packageName)?.component,
),
)
withContext(Dispatchers.IO) {
defaultWablePreferenceDatasource.clear()
}
ProcessPhoenix.triggerRebirth(context)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.MultipartBody

suspend fun ContentResolver.createImagePart(uriString: String?): MultipartBody.Part? {
suspend fun ContentResolver.createImagePart(uriString: String?, fileName: String): MultipartBody.Part? {
if (uriString.isNullOrEmpty()) return null
val uri = runCatching { Uri.parse(uriString) }.getOrElse { return null }

return withContext(Dispatchers.IO) {
val imageRequestBody = ContentUriRequestBody(this@createImagePart, uri)
imageRequestBody.toMultiPartData("image")
imageRequestBody.toMultiPartData(fileName)
}
}
1 change: 1 addition & 0 deletions core/ui/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<item name="android:statusBarColor">@android:color/white</item>
<item name="android:windowLightStatusBar">true</item>
<item name="android:windowBackground">@color/white</item>
<item name="android:windowIsTranslucent">true</item>
</style>

<style name="Theme.Wable" parent="Base.Theme.Wable" />
Expand Down
4 changes: 0 additions & 4 deletions feature/auth/src/main/java/com/teamwable/auth/LoginScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ fun LoginRoute(

val showDialog by viewModel.showDialog.collectAsStateWithLifecycle()

LaunchedEffect(Unit) {
viewModel.observeAutoLogin()
}

LaunchedEffect(lifecycleOwner) {
viewModel.loginSideEffect.flowWithLifecycle(lifecycleOwner.lifecycle)
.collect { sideEffect ->
Expand Down
11 changes: 0 additions & 11 deletions feature/auth/src/main/java/com/teamwable/auth/LoginViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject
Expand All @@ -34,16 +33,6 @@ class LoginViewModel @Inject constructor(
private val _showDialog = MutableStateFlow(false)
val showDialog: StateFlow<Boolean> get() = _showDialog

fun observeAutoLogin() {
viewModelScope.launch {
userInfoRepository.getAutoLogin().collectLatest { isAutoLogin ->
if (isAutoLogin) {
_loginSideEffect.emit(LoginSideEffect.NavigateToMain)
}
}
}
}

fun showLoginDialog(show: Boolean) {
_showDialog.update { show }
}
Expand Down
1 change: 1 addition & 0 deletions feature/main-compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ android {
dependencies {
implementation(project(":feature:auth"))
implementation(project(":feature:onboarding"))
implementation(libs.lottie.compose)
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class MainNavigator(
@Composable get() = navController
.currentBackStackEntryAsState().value?.destination

val startDestination = Route.Login
val startDestination = Route.Splash

fun navigateToLogin(navOptions: NavOptions) {
navController.navigateLogin(navOptions)
Expand Down Expand Up @@ -57,8 +57,8 @@ class MainNavigator(

fun resetToLogin() {
val navOptions = navOptions {
popUpTo(startDestination) {
saveState = true
popUpTo(Route.Login) {
inclusive = true
}
launchSingleTop = true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ internal fun MainScreen(
)
},
navigateToHome = { startActivity(localContext, intent, null) },
intentProvider = intentProvider,
)
loginNavGraph(
navigateToFirstLckWatch = { navigator.navigateToFirstLckWatch() },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.teamwable.main_compose.splash

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.flowWithLifecycle
import com.airbnb.lottie.LottieComposition
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.animateLottieCompositionAsState
import com.airbnb.lottie.compose.rememberLottieComposition
import com.teamwable.designsystem.theme.WableTheme
import com.teamwable.main_compose.R
import com.teamwable.main_compose.splash.model.SplashSideEffect
import kotlinx.coroutines.delay

@Composable
fun SplashRoute(
viewModel: SplashViewModel = hiltViewModel(),
navigateToHome: () -> Unit,
navigateToLogIn: () -> Unit,
) {
val lifecycleOwner = LocalLifecycleOwner.current
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.wable_splash))
val progress by animateLottieCompositionAsState(
composition = composition,
iterations = LottieConstants.IterateForever,
)

LaunchedEffect(Unit) {
delay(2000)
viewModel.observeAutoLogin()
}

LaunchedEffect(lifecycleOwner) {
viewModel.sideEffect.flowWithLifecycle(lifecycleOwner.lifecycle)
.collect { sideEffect ->
when (sideEffect) {
is SplashSideEffect.NavigateToHome -> navigateToHome()
is SplashSideEffect.NavigateToLogin -> navigateToLogIn()
}
}
}

WableSplashScreen(
composition = composition,
progress = progress,
)
}

@Composable
fun WableSplashScreen(
composition: LottieComposition?,
progress: Float,
) {
Box(
modifier = Modifier.fillMaxSize(),
) {
LottieAnimation(
composition = composition,
progress = { progress },
modifier = Modifier.align(Alignment.Center),
)
}
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
WableTheme {
WableSplashScreen(
composition = rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.wable_splash)).value,
progress = 1.0f,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.teamwable.main_compose.splash

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.teamwable.data.repository.UserInfoRepository
import com.teamwable.main_compose.splash.model.SplashSideEffect
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class SplashViewModel @Inject constructor(
private val userInfoRepository: UserInfoRepository,
) : ViewModel() {
private val _sideEffect = MutableSharedFlow<SplashSideEffect>()
val sideEffect: SharedFlow<SplashSideEffect> = _sideEffect.asSharedFlow()

fun observeAutoLogin() {
viewModelScope.launch {
userInfoRepository.getAutoLogin().collectLatest { isAutoLogin ->
if (isAutoLogin) _sideEffect.emit(SplashSideEffect.NavigateToHome)
else _sideEffect.emit(SplashSideEffect.NavigateToLogin)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.teamwable.main_compose.splash.model

sealed interface SplashSideEffect {
data object NavigateToHome : SplashSideEffect

data object NavigateToLogin : SplashSideEffect
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@ package com.teamwable.main_compose.splash.navigation

import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.teamwable.common.intentprovider.IntentProvider
import com.teamwable.main_compose.splash.SplashRoute
import com.teamwable.navigation.Route

fun NavGraphBuilder.splashNavGraph(
navigateToLogIn: () -> Unit,
navigateToHome: () -> Unit,
intentProvider: IntentProvider,
) {
composable<Route.Splash> {
/* SplashScreen(
navigateToHome = navigateToHome,
navigateToLogIn = navigateToLogIn
intentProvider: IntentProvider,
)*/
SplashRoute(
navigateToHome = navigateToHome,
navigateToLogIn = navigateToLogIn,
)
}
}
Loading

0 comments on commit b203125

Please sign in to comment.