Skip to content
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ android {
applicationId = "com.eatssu.android"
minSdk = 28
targetSdk = 37
versionCode = 66
versionName = "3.2.13"
versionCode = 69
versionName = "3.2.14"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,25 @@ data class GetMealResponse(
data class MenusInformationList(
@SerialName("menuId") val menuId: Long? = null,
@SerialName("name") val name: String? = null,
@SerialName("isMain") val isMain: Boolean = false,
)

fun List<GetMealResponse>.mapTodayMenuResponseToMenu(): List<Menu> {
@Serializable
data class GetMealMenusInfoResponse(
@SerialName("briefMenus") val briefMenus: List<MenusInformationList> = emptyList(),
)

fun List<GetMealResponse>.mapTodayMenuResponseToMenu(
showMainMenusOnly: Boolean = false,
): List<Menu> {
val menuList = mutableListOf<Menu>()

this.forEach { mealResponse ->
val menuNames =
mealResponse.briefMenus.mapNotNull { it.name }.joinToString(separator = MENU_SEPARATOR)
mealResponse.briefMenus
.menusForDisplay(showMainMenusOnly)
.mapNotNull { it.name?.takeIf(String::isNotBlank) }
.joinToString(separator = MENU_SEPARATOR)
val mealId = mealResponse.mealId ?: -1
val price = mealResponse.price ?: 0
val mainRating = mealResponse.rating ?: 0.0
Expand All @@ -39,8 +50,23 @@ fun List<GetMealResponse>.mapTodayMenuResponseToMenu(): List<Menu> {
}


fun List<GetMealResponse>.toDomain(): List<List<String>> {
fun List<GetMealResponse>.toDomain(
showMainMenusOnly: Boolean = false,
): List<List<String>> {
return this.map { meal ->
meal.briefMenus.mapNotNull { it.name }
meal.briefMenus
.menusForDisplay(showMainMenusOnly)
.mapNotNull { it.name?.takeIf(String::isNotBlank) }
}
}

fun GetMealMenusInfoResponse.toMenuNames(): List<String> =
briefMenus.mapNotNull { it.name?.takeIf(String::isNotBlank) }

private fun List<MenusInformationList>.menusForDisplay(
showMainMenusOnly: Boolean,
): List<MenusInformationList> {
if (!showMainMenusOnly) return this

return filter { it.isMain }.ifEmpty { this }
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
import kotlinx.coroutines.tasks.await
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.jsonArray
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
Expand Down Expand Up @@ -62,7 +64,11 @@ class FirebaseRemoteConfigRepositoryImpl @Inject constructor(

private fun parseCafeteriaJson(jsonString: String): List<RestaurantInfo> {
return try {
json.decodeFromString<List<RestaurantInfo>>(jsonString).also {
json.parseToJsonElement(jsonString).jsonArray.mapNotNull { element ->
runCatching { json.decodeFromJsonElement<RestaurantInfo>(element) }
.onFailure { Timber.w(it, "지원하지 않는 식당 정보 제외: $element") }
.getOrNull()
}.also {
Timber.d("Loaded cafeteria info: $it")
}
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,63 @@
package com.eatssu.android.data.remote.repository

import com.eatssu.android.data.local.SettingDataStore
import com.eatssu.android.data.model.map
import com.eatssu.android.data.model.orEmptyList
import com.eatssu.android.data.model.orNull
import com.eatssu.android.data.remote.dto.response.mapTodayMenuResponseToMenu
import com.eatssu.android.data.remote.dto.response.toMenuNames
import com.eatssu.android.data.remote.dto.response.toDomain
import com.eatssu.android.data.remote.service.MealService
import com.eatssu.android.domain.model.Menu
import com.eatssu.android.domain.repository.MealRepository
import com.eatssu.common.enums.AppLanguage
import com.eatssu.common.enums.Restaurant
import com.eatssu.common.enums.Time
import kotlinx.coroutines.flow.first
import javax.inject.Inject

private const val ENGLISH_MEAL_LANGUAGE = "EN"

class MealRepositoryImpl @Inject constructor(
private val mealService: MealService,
private val settingDataStore: SettingDataStore,
) : MealRepository {

override suspend fun getTodayMeal(
date: String,
restaurant: String,
time: String
): List<List<String>> {
return mealService.getTodayMeal(date, restaurant, time).orEmptyList().toDomain()
val language = getMealLanguage()
return mealService.getTodayMeal(date, restaurant, time, language)
.orEmptyList()
.toDomain(showMainMenusOnly = language != null)
}

override suspend fun getTodayMenuList(
date: String,
restaurant: Restaurant,
time: Time
): List<Menu> {
return mealService.getTodayMeal(date, restaurant.toString(), time.toString())
.map { it.mapTodayMenuResponseToMenu() }
val language = getMealLanguage()
return mealService.getTodayMeal(date, restaurant.toString(), time.toString(), language)
.map { it.mapTodayMenuResponseToMenu(showMainMenusOnly = language != null) }
.orEmptyList()
}

override suspend fun getMealMenuNames(mealId: Long): List<String> {
return mealService.getMealMenusInfo(mealId, getMealLanguage())
.orNull()
?.toMenuNames()
.orEmpty()
}

private suspend fun getMealLanguage(): String? {
return when (settingDataStore.appLanguage.first()) {
AppLanguage.KOREAN -> null
AppLanguage.ENGLISH,
AppLanguage.JAPANESE,
AppLanguage.VIETNAMESE -> ENGLISH_MEAL_LANGUAGE
}
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
package com.eatssu.android.data.remote.repository

import com.eatssu.android.data.local.SettingDataStore
import com.eatssu.android.data.model.map
import com.eatssu.android.data.model.orEmptyList
import com.eatssu.android.data.remote.dto.response.mapFixedMenuResponseToMenu
import com.eatssu.android.data.remote.service.MenuService
import com.eatssu.android.domain.model.Menu
import com.eatssu.android.domain.repository.MenuRepository
import com.eatssu.common.enums.AppLanguage
import com.eatssu.common.enums.Restaurant
import kotlinx.coroutines.flow.first
import javax.inject.Inject

private const val ENGLISH_FIXED_MENU_LANGUAGE = "EN"

class MenuRepositoryImpl @Inject constructor(
private val menuService: MenuService
private val menuService: MenuService,
private val settingDataStore: SettingDataStore,
) : MenuRepository {
override suspend fun getFixedMenuList(restaurant: Restaurant): List<Menu> {
return menuService.getFixMenu(restaurant.toString())
val language = when (settingDataStore.appLanguage.first()) {
AppLanguage.KOREAN -> null
AppLanguage.ENGLISH,
AppLanguage.JAPANESE,
AppLanguage.VIETNAMESE -> ENGLISH_FIXED_MENU_LANGUAGE
}
return menuService.getFixMenu(restaurant.toString(), language)
.map { it.mapFixedMenuResponseToMenu() }
.orEmptyList()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.eatssu.android.data.remote.service

import com.eatssu.android.data.model.ApiResult
import com.eatssu.android.data.remote.dto.response.GetMealMenusInfoResponse
import com.eatssu.android.data.remote.dto.response.GetMealResponse
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query

interface MealService {
Expand All @@ -14,6 +16,12 @@ interface MealService {
@Query("date") date: String,
@Query("restaurant") restaurant: String,
@Query("time") time: String,
@Query("language") language: String? = null,
): ApiResult<List<GetMealResponse>>

@GET("meals/{mealId}/menus-info")
suspend fun getMealMenusInfo(
@Path("mealId") mealId: Long,
@Query("language") language: String? = null,
): ApiResult<GetMealMenusInfoResponse>
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface MenuService {
@GET("menus")
suspend fun getFixMenu(
@Query("restaurant") restaurant: String,
@Query("language") language: String? = null,
): ApiResult<GetFixedMenuResponse>

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@ interface MealRepository {
restaurant: Restaurant,
time: Time,
): List<Menu>

/**
* 변동 식단 상세 화면에 표시할 전체 메뉴 이름을 가져온다.
*/
suspend fun getMealMenuNames(mealId: Long): List<String>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.eatssu.android.domain.usecase.menu

import com.eatssu.android.domain.repository.MealRepository
import javax.inject.Inject

class GetMealMenuNamesUseCase @Inject constructor(
private val mealRepository: MealRepository,
) {
suspend operator fun invoke(mealId: Long): List<String> =
mealRepository.getMealMenuNames(mealId)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ class LoadMenusUseCase @Inject constructor(
addAll(Restaurant.getVariableRestaurantList())

if (shouldIncludeFixedRestaurants(date = date, time = time, isPublicHoliday = isPublicHoliday)) {
add(Restaurant.FOOD_COURT)
add(Restaurant.SNACK_CORNER)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ class GetUserCollegeDepartmentUseCase @Inject constructor(
val nickname = accountDataStore.name.first()
val college = accountDataStore.college.first() ?: College(
collegeId = -1,
collegeName = "단과대"
collegeName = ""
)
val department = accountDataStore.department.first() ?: Department(
departmentId = -1,
departmentName = "학과"
departmentName = ""
)
return UserInfo(nickname, department, college)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class MainViewModel @Inject constructor(
val userInfo = getUserCollegeDepartmentUseCase()
_uiState.value = UiState.Success(
MainState.DepartmentState(
collegeName = userInfo.userCollege.collegeName,
departmentName = userInfo.userDepartment.departmentName
)
)
Expand Down Expand Up @@ -146,6 +147,7 @@ class MainViewModel @Inject constructor(
val userInfo = getUserCollegeDepartmentUseCase()
_uiState.value = UiState.Success(
MainState.DepartmentState(
collegeName = userInfo.userCollege.collegeName,
departmentName = userInfo.userDepartment.departmentName,
showUserDepartmentBottomSheet =
(userInfo.userCollege.collegeId == -1 || userInfo.userDepartment.departmentId == -1)
Expand All @@ -169,6 +171,7 @@ class MainViewModel @Inject constructor(

_uiState.value = UiState.Success(
MainState.DepartmentState(
collegeName = college.collegeName,
departmentName = department.departmentName,
showUserDepartmentBottomSheet =
(college.collegeId == -1 || department.departmentId == -1)
Expand Down Expand Up @@ -201,6 +204,7 @@ sealed class MainState {
object NicknameNull : MainState()
object LoggedOut : MainState()
data class DepartmentState(
val collegeName: String? = "",
val departmentName: String? = "",
val showUserDepartmentBottomSheet: Boolean = false
) : MainState()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.eatssu.android.presentation.cafeteria.review

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.appcompat.app.AppCompatActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Arrangement
Expand All @@ -16,10 +16,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.rememberNavController
import com.eatssu.android.R
import com.eatssu.android.analytics.ProvideAnalyticsTracker
import com.eatssu.common.analytics.AnalyticsTracker
import com.eatssu.common.enums.MenuType
Expand All @@ -31,7 +33,7 @@ import javax.inject.Inject
import kotlin.properties.Delegates

@AndroidEntryPoint
class ReviewComposeActivity : ComponentActivity() {
class ReviewComposeActivity : AppCompatActivity() {

@Inject
lateinit var analyticsTracker: AnalyticsTracker
Expand Down Expand Up @@ -92,14 +94,14 @@ class ReviewComposeActivity : ComponentActivity() {
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "메뉴 정보를 불러오는데 실패했습니다.\n다시 시도해주세요.",
text = stringResource(R.string.review_menu_info_load_failed),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurface
)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = onBackClick) {
Text(text = "뒤로가기")
Text(text = stringResource(R.string.nav_back))
}
}
}
Expand Down
Loading
Loading