Skip to content

Commit

Permalink
Merge pull request #116 from Nexters/release/1.2.0
Browse files Browse the repository at this point in the history
[Release] v1.2.0 버전 업데이트 - master
  • Loading branch information
ham2174 authored Mar 3, 2024
2 parents 8980b69 + 5c7d48d commit d39401c
Show file tree
Hide file tree
Showing 73 changed files with 1,676 additions and 229 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ dependencies {
implementation(projects.feature.home)
implementation(projects.feature.match)
implementation(projects.feature.onboarding)
implementation(projects.feature.collection)
// implementation(libs.coil.core)
implementation(libs.startup)
// implementation(libs.security)
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/moya/funch/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import androidx.activity.compose.setContent
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.moya.funch.datastore.UserDataStore
Expand All @@ -28,7 +28,7 @@ class MainActivity : ComponentActivity() {
installSplashScreen()
setContent {
FunchTheme {
var showLoading by remember { mutableStateOf(true) }
var showLoading by rememberSaveable { mutableStateOf(true) }

LaunchedEffect(Unit) {
delay(1500)
Expand Down
32 changes: 32 additions & 0 deletions app/src/main/java/com/moya/funch/di/MbtiCollectionModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.moya.funch.di

import com.moya.funch.repository.MbtiCollectionRepository
import com.moya.funch.repository.MbtiCollectionRepositoryImpl
import com.moya.funch.usecase.LoadMbtiCollectionUseCase
import com.moya.funch.usecase.LoadMbtiCollectionUseCaseImpl
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object MbtiCollectionModule {

@Module
@InstallIn(SingletonComponent::class)
interface UseCaseBinder {
@Binds
@Singleton
fun bindLoadMbtiCollectionUseCase(useCase: LoadMbtiCollectionUseCaseImpl): LoadMbtiCollectionUseCase
}

@Module
@InstallIn(SingletonComponent::class)
interface RepositoryBinder {
@Binds
@Singleton
fun bindMbtiCollectionRepository(repository: MbtiCollectionRepositoryImpl): MbtiCollectionRepository
}
}
26 changes: 19 additions & 7 deletions app/src/main/java/com/moya/funch/navigation/FunchNavHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navOptions
import com.moya.funch.collection.navigation.collectionScreen
import com.moya.funch.collection.navigation.navigateToCollection
import com.moya.funch.match.navigation.matchingScreen
import com.moya.funch.match.navigation.navigateToMatching
import com.moya.funch.onboarding.navigation.ON_BOARDING_ROUTE
import com.moya.funch.onboarding.navigation.navigateToOnBoarding
import com.moya.funch.onboarding.navigation.onBoardingScreen

@Composable
Expand All @@ -20,29 +23,38 @@ fun FunchNavHost(hasProfile: Boolean, navController: NavHostController = remembe
with(navController) {
profileGraph(
onNavigateToHome = ::onNavigateToHome,
onCloseMyProfile = ::onCloseMyProfile,
onNavigateCreateProfile = ::onNavigateToCreateProfile
onCloseMyProfile = { onPopBackstackUpTo(HOME_ROUTE) },
onNavigateOnBoarding = ::onNavigateOnBoarding
)
homeScreen(
onNavigateToMatching = ::onNavigateToMatching,
onNavigateToMyProfile = ::onNavigateToMyProfile
onNavigateToMyProfile = ::onNavigateToMyProfile,
onNavigateToCollection = ::navigateToCollection
)
matchingScreen(onClose = { popBackStack(HOME_ROUTE, false) })
onBoardingScreen(onNavigateToCreateProfile = ::navigateToCreateProfile)
collectionScreen(onNavigateToHome = ::onNavigateToHome)
}
}
}

private fun NavController.onNavigateToCreateProfile() =
navigateToCreateProfile(navOptions { popUpTo(graph.id) { inclusive = true } })

private fun NavController.onNavigateToMyProfile() = navigateToMyProfile(singleTopNavOptions)
private fun NavController.onNavigateOnBoarding() = navigateToOnBoarding {
launchSingleTop = true
popUpTo(HOME_ROUTE) { inclusive = true }
}

private fun NavController.onNavigateToMyProfile() = navigateToMyProfile(singleTopPopUpTo())

private fun NavController.onNavigateToMatching(route: String) = navigateToMatching(route, singleTopPopUpTo())

private fun NavController.onNavigateToMatching(route: String) = navigateToMatching(route, singleTopNavOptions)
private fun NavController.onPopBackstackUpTo(route: String) = popBackStack(route = route, inclusive = false)

private val singleTopNavOptions = navOptions {
private fun singleTopPopUpTo(route: String = HOME_ROUTE) = navOptions {
launchSingleTop = true
popUpTo(HOME_ROUTE)
popUpTo(route)
}

private fun determineStartDestination(hasProfile: Boolean): String {
Expand Down
23 changes: 7 additions & 16 deletions app/src/main/java/com/moya/funch/splash/SplashScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.moya.funch.splash

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -19,7 +18,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieComposition
import com.moya.funch.R
import com.moya.funch.theme.FunchTheme
Expand All @@ -42,28 +40,21 @@ fun LoadingScreen() {
Surface(
color = FunchTheme.colors.background
) {
Column(
Box(
modifier = Modifier
.fillMaxSize()
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
LottieAnimation(
composition = splashIcon,
iterations = LottieConstants.IterateForever
composition = splashBackground,
iterations = 1
)
LottieAnimation(
composition = splashBackground,
iterations = LottieConstants.IterateForever
composition = splashIcon,
iterations = 1
)
}

Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Image(painter = painterResource(id = R.drawable.ic_splash_logo), contentDescription = "Splash Logo")
}

Box(
modifier = Modifier
.fillMaxSize(),
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/raw/funch_splash_icon_lottie.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ import com.moya.funch.model.ProfileModel

interface LocalUserDataSource : UserDataSource {
suspend fun saveUserProfile(userModel: ProfileModel): Result<Unit>

suspend fun fetchUserMbtiCollection(): Result<Set<String>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ class LocalUserDataSourceImpl @Inject constructor(
}
}
}

override suspend fun fetchUserMbtiCollection(): Result<Set<String>> = runCatching { userDataStore.mbtiCollection }
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@ class RemoteMatchDataSourceImpl @Inject constructor(
targetCode = targetCode
)
)
}.mapCatching { it.data }
}.mapCatching {
saveMbtiCollection(it.data.profile.mbti)
it.data
}
}

private fun saveMbtiCollection(mbti: String) {
dataStore.mbtiCollection = dataStore.mbtiCollection.toMutableSet().apply {
add(mbti)
}.toSet()
}

override suspend fun canMatchProfile(targetCode: String): Result<Boolean> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.moya.funch.repository

import com.moya.funch.datasource.local.LocalUserDataSource
import com.moya.funch.entity.Mbti
import javax.inject.Inject

class MbtiCollectionRepositoryImpl @Inject constructor(
private val localUserDataSource: LocalUserDataSource
) : MbtiCollectionRepository {
override suspend fun addMbtiCollection(): Result<Unit> {
// @Gun Hyung Todo : 추후 데이터 레이어 리팩토링 이후 작업 진행
return Result.success(Unit)
}

override suspend fun loadMbtiCollection(): Result<List<Mbti>> {
return localUserDataSource.fetchUserMbtiCollection().mapCatching { mbtiList ->
mbtiList.map { mbti -> Mbti.valueOf(mbti) }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,20 @@ internal class LocalUserDataSourceImplTest {
)
}

@Test
fun `MbtiCollection이 비어있으면 emptySet를 가져온다`() = runTest {
// given
coEvery { userDataStore.mbtiCollection } returns emptySet()
// when
val actualResult = localUserDataSource.fetchUserMbtiCollection()
// then
assertAll(
{ coVerify(exactly = 1) { userDataStore.mbtiCollection } },
{ assertThat(actualResult.isSuccess).isTrue() },
{ assertThat(actualResult.getOrNull()).isEmpty() }
)
}

companion object {
@JvmField
@RegisterExtension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface UserDataStore {
var subwayName: String
var subwayLines: Set<String>
var mbti: String
var mbtiCollection: Set<String>

fun hasUserCode(): Boolean

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ class UserDataStoreImpl @Inject constructor(
}
}

override var mbtiCollection: Set<String>
get() = preferences.getStringSet(MBTI_COLLECTION, setOf()).orEmpty()
set(value) {
preferences.edit(commit = true) {
putStringSet(MBTI_COLLECTION, value)
}
}

override fun hasUserCode(): Boolean {
return preferences.contains(USER_CODE)
}
Expand Down Expand Up @@ -123,5 +131,6 @@ class UserDataStoreImpl @Inject constructor(
const val SUBWAY_NAME = "SUBWAY_NAME"
const val SUBWAY_LINE = "SUBWAY_LINE"
const val MBTI = "MBTI"
const val MBTI_COLLECTION = "MBTI_COLLECTION"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,45 @@ fun subwayLinePainter(value: String): Painter = when (value) {
"INCHEON_TWO" -> painterResource(id = FunchIconAsset.SubwayLine.subway_line_incheon_two)
else -> throw IllegalArgumentException("Unknown Icon: $value")
}

@Composable
fun activeMbtiBadgePainter(value: String): Painter = when (value) {
"ISTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.istj_active)
"ISFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.isfj_active)
"INFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.infj_active)
"INTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.intj_active)
"ISTP" -> painterResource(id = FunchIconAsset.MbtiBadge.istp_active)
"ISFP" -> painterResource(id = FunchIconAsset.MbtiBadge.isfp_active)
"INFP" -> painterResource(id = FunchIconAsset.MbtiBadge.infp_active)
"INTP" -> painterResource(id = FunchIconAsset.MbtiBadge.intp_active)
"ESTP" -> painterResource(id = FunchIconAsset.MbtiBadge.estp_active)
"ESFP" -> painterResource(id = FunchIconAsset.MbtiBadge.esfp_active)
"ENFP" -> painterResource(id = FunchIconAsset.MbtiBadge.enfp_active)
"ENTP" -> painterResource(id = FunchIconAsset.MbtiBadge.entp_active)
"ESTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.estj_active)
"ESFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.esfj_active)
"ENFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.enfj_active)
"ENTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.entj_active)
else -> throw IllegalArgumentException("Unknown Icon: $value")
}

@Composable
fun inactiveMbtiBadgePainter(value: String): Painter = when (value) {
"ISTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.istj_inactive)
"ISFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.isfj_inactive)
"INFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.infj_inactive)
"INTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.intj_inactive)
"ISTP" -> painterResource(id = FunchIconAsset.MbtiBadge.istp_inactive)
"ISFP" -> painterResource(id = FunchIconAsset.MbtiBadge.isfp_inactive)
"INFP" -> painterResource(id = FunchIconAsset.MbtiBadge.infp_inactive)
"INTP" -> painterResource(id = FunchIconAsset.MbtiBadge.intp_inactive)
"ESTP" -> painterResource(id = FunchIconAsset.MbtiBadge.estp_inactive)
"ESFP" -> painterResource(id = FunchIconAsset.MbtiBadge.esfp_inactive)
"ENFP" -> painterResource(id = FunchIconAsset.MbtiBadge.enfp_inactive)
"ENTP" -> painterResource(id = FunchIconAsset.MbtiBadge.entp_inactive)
"ESTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.estj_inactive)
"ESFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.esfj_inactive)
"ENFJ" -> painterResource(id = FunchIconAsset.MbtiBadge.enfj_inactive)
"ENTJ" -> painterResource(id = FunchIconAsset.MbtiBadge.entj_inactive)
else -> throw IllegalArgumentException("Unknown Icon: $value")
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ object FunchIconAsset {
val profile_80 = R.drawable.ic_profile_80
val view_count_80 = R.drawable.ic_view_count_80
val code_80 = R.drawable.ic_code_80
val trophy_40 = R.drawable.ic_trophy_40
}

object Job {
Expand Down Expand Up @@ -89,4 +90,42 @@ object FunchIconAsset {
val eighty = R.drawable.ic_match_percentage80_120
val hundred = R.drawable.ic_match_percentage100_120
}

object MbtiBadge {
/* active */
val infj_active = R.drawable.ic_mbti_infj_active_60
val intj_active = R.drawable.ic_mbti_intj_active_60
val infp_active = R.drawable.ic_mbti_infp_active_60
val intp_active = R.drawable.ic_mbti_intp_active_60
val isfj_active = R.drawable.ic_mbti_isfj_active_60
val istj_active = R.drawable.ic_mbti_istj_active_60
val isfp_active = R.drawable.ic_mbti_isfp_active_60
val istp_active = R.drawable.ic_mbti_istp_active_60
val entj_active = R.drawable.ic_mbti_entj_active_60
val enfp_active = R.drawable.ic_mbti_enfp_active_60
val enfj_active = R.drawable.ic_mbti_enfj_active_60
val entp_active = R.drawable.ic_mbti_entp_active_60
val esfj_active = R.drawable.ic_mbti_esfj_active_60
val esfp_active = R.drawable.ic_mbti_esfp_active_60
val estj_active = R.drawable.ic_mbti_estj_active_60
val estp_active = R.drawable.ic_mbti_estp_active_60

/* inactive */
val infj_inactive = R.drawable.ic_mbti_infj_inactive_60
val intj_inactive = R.drawable.ic_mbti_intj_inactive_60
val infp_inactive = R.drawable.ic_mbti_infp_inactive_60
val intp_inactive = R.drawable.ic_mbti_intp_inactive_60
val isfj_inactive = R.drawable.ic_mbti_isfj_inactive_60
val istj_inactive = R.drawable.ic_mbti_istj_inactive_60
val isfp_inactive = R.drawable.ic_mbti_isfp_inactive_60
val istp_inactive = R.drawable.ic_mbti_istp_inactive_60
val entj_inactive = R.drawable.ic_mbti_entj_inactive_60
val enfp_inactive = R.drawable.ic_mbti_enfp_inactive_60
val enfj_inactive = R.drawable.ic_mbti_enfj_inactive_60
val entp_inactive = R.drawable.ic_mbti_entp_inactive_60
val esfj_inactive = R.drawable.ic_mbti_esfj_inactive_60
val esfp_inactive = R.drawable.ic_mbti_esfp_inactive_60
val estj_inactive = R.drawable.ic_mbti_estj_inactive_60
val estp_inactive = R.drawable.ic_mbti_estp_inactive_60
}
}
Loading

0 comments on commit d39401c

Please sign in to comment.