캐릭터 상세 - 폰 언어 설정에 따라 번역 데이터를 조회하도록 수정
This commit is contained in:
@@ -6,12 +6,12 @@ import kr.co.vividnext.sodalive.chat.character.detail.gallery.CharacterImageList
|
||||
import kr.co.vividnext.sodalive.chat.character.detail.gallery.CharacterImagePurchaseRequest
|
||||
import kr.co.vividnext.sodalive.chat.character.detail.gallery.CharacterImagePurchaseResponse
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface CharacterApi {
|
||||
@GET("/api/chat/character/main")
|
||||
@@ -22,7 +22,8 @@ interface CharacterApi {
|
||||
@GET("/api/chat/character/{characterId}")
|
||||
fun getCharacterDetail(
|
||||
@Header("Authorization") authHeader: String,
|
||||
@Path("characterId") characterId: Long
|
||||
@Path("characterId") characterId: Long,
|
||||
@Query("languageCode") languageCode: String
|
||||
): Single<ApiResponse<CharacterDetailResponse>>
|
||||
|
||||
@GET("/api/chat/character/image/list")
|
||||
|
||||
@@ -23,6 +23,7 @@ import kr.co.vividnext.sodalive.chat.character.detail.CharacterDetailActivity.Co
|
||||
import kr.co.vividnext.sodalive.chat.talk.room.ChatRoomActivity
|
||||
import kr.co.vividnext.sodalive.common.LoadingDialog
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.common.Utils.getCurrentLanguageCode
|
||||
import kr.co.vividnext.sodalive.databinding.FragmentCharacterDetailBinding
|
||||
import kr.co.vividnext.sodalive.extensions.dpToPx
|
||||
import org.koin.android.ext.android.inject
|
||||
@@ -78,7 +79,7 @@ class CharacterDetailFragment : BaseFragment<FragmentCharacterDetailBinding>(
|
||||
setupView()
|
||||
bindObservers()
|
||||
|
||||
viewModel.load(characterId)
|
||||
viewModel.load(characterId, languageCode = getCurrentLanguageCode(requireContext()))
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@@ -117,7 +118,7 @@ class CharacterDetailFragment : BaseFragment<FragmentCharacterDetailBinding>(
|
||||
// 기본 정보
|
||||
if (detail.gender != null) {
|
||||
binding.tvGender.visibility = View.VISIBLE
|
||||
binding.tvGender.text = detail.gender
|
||||
binding.tvGender.text = detail.translated?.gender ?: detail.gender
|
||||
|
||||
if (detail.gender == "남성") {
|
||||
binding.tvGender.setTextColor(
|
||||
@@ -164,7 +165,7 @@ class CharacterDetailFragment : BaseFragment<FragmentCharacterDetailBinding>(
|
||||
View.VISIBLE
|
||||
}
|
||||
|
||||
binding.tvCharacterName.text = detail.name
|
||||
binding.tvCharacterName.text = detail.translated?.name ?: detail.name
|
||||
binding.tvCharacterStatus.text = when (detail.characterType) {
|
||||
CharacterType.CLONE -> getString(R.string.chat_character_type_clone)
|
||||
CharacterType.CHARACTER -> getString(R.string.chat_character_type_character)
|
||||
@@ -176,11 +177,13 @@ class CharacterDetailFragment : BaseFragment<FragmentCharacterDetailBinding>(
|
||||
CharacterType.CHARACTER -> R.drawable.bg_character_status_character
|
||||
}
|
||||
)
|
||||
binding.tvCharacterDescription.text = detail.description
|
||||
binding.tvCharacterTags.text = detail.tags
|
||||
binding.tvCharacterDescription.text = detail.translated?.description
|
||||
?: detail.description
|
||||
binding.tvCharacterTags.text = detail.translated?.tags ?: detail.tags
|
||||
|
||||
// 세계관 내용과 버튼 가시성 초기화
|
||||
val worldviewText = detail.backgrounds?.description.orEmpty()
|
||||
val worldviewText = detail.translated?.background?.description
|
||||
?: detail.backgrounds?.description.orEmpty()
|
||||
binding.tvWorldviewContent.text = worldviewText
|
||||
// 먼저 전체 줄 수를 측정한 뒤 접힘 레이아웃 적용
|
||||
binding.tvWorldviewContent.post {
|
||||
@@ -196,7 +199,8 @@ class CharacterDetailFragment : BaseFragment<FragmentCharacterDetailBinding>(
|
||||
}
|
||||
|
||||
// 성격 내용과 버튼 가시성 초기화
|
||||
val personalityText = detail.personalities?.description.orEmpty()
|
||||
val personalityText = detail.translated?.personality?.description
|
||||
?: detail.personalities?.description.orEmpty()
|
||||
binding.tvPersonalityContent.text = personalityText
|
||||
// 먼저 전체 줄 수를 측정한 뒤 접힘 레이아웃 적용
|
||||
binding.tvPersonalityContent.post {
|
||||
@@ -313,7 +317,10 @@ class CharacterDetailFragment : BaseFragment<FragmentCharacterDetailBinding>(
|
||||
if (resp.success) {
|
||||
binding.etCommentInput.setText("")
|
||||
showToast(getString(R.string.character_detail_comment_register_success))
|
||||
viewModel.load(targetCharacterId)
|
||||
viewModel.load(
|
||||
targetCharacterId,
|
||||
languageCode = getCurrentLanguageCode(requireContext())
|
||||
)
|
||||
} else {
|
||||
showToast(
|
||||
resp.message ?: getString(R.string.common_error_request)
|
||||
|
||||
@@ -8,8 +8,15 @@ class CharacterDetailRepository(
|
||||
private val characterApi: CharacterApi,
|
||||
private val talkApi: TalkApi
|
||||
) {
|
||||
fun getCharacterDetail(token: String, characterId: Long) =
|
||||
characterApi.getCharacterDetail(authHeader = token, characterId = characterId)
|
||||
fun getCharacterDetail(
|
||||
token: String,
|
||||
characterId: Long,
|
||||
languageCode: String
|
||||
) = characterApi.getCharacterDetail(
|
||||
authHeader = token,
|
||||
characterId = characterId,
|
||||
languageCode = languageCode
|
||||
)
|
||||
|
||||
fun createChatRoom(token: String, request: CreateChatRoomRequest) =
|
||||
talkApi.createChatRoom(authHeader = token, request = request)
|
||||
|
||||
@@ -21,7 +21,8 @@ data class CharacterDetailResponse(
|
||||
@SerializedName("characterType") val characterType: CharacterType,
|
||||
@SerializedName("others") val others: List<OtherCharacter>,
|
||||
@SerializedName("latestComment") val latestComment: CharacterCommentResponse?,
|
||||
@SerializedName("totalComments") val totalComments: Int
|
||||
@SerializedName("totalComments") val totalComments: Int,
|
||||
@SerializedName("translated") val translated: TranslatedAiCharacterDetail?
|
||||
)
|
||||
|
||||
@Keep
|
||||
@@ -51,3 +52,25 @@ data class CharacterBackgroundResponse(
|
||||
@SerializedName("topic") val topic: String,
|
||||
@SerializedName("description") val description: String
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class TranslatedAiCharacterDetail(
|
||||
@SerializedName("name") val name: String?,
|
||||
@SerializedName("description") val description: String?,
|
||||
@SerializedName("gender") val gender: String?,
|
||||
@SerializedName("personality") val personality: TranslatedAiCharacterPersonality?,
|
||||
@SerializedName("background") val background: TranslatedAiCharacterBackground?,
|
||||
@SerializedName("tags") val tags: String?
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class TranslatedAiCharacterPersonality(
|
||||
@SerializedName("trait") val trait: String?,
|
||||
@SerializedName("description") val description: String?
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class TranslatedAiCharacterBackground(
|
||||
@SerializedName("topic") val topic: String?,
|
||||
@SerializedName("description") val description: String?
|
||||
)
|
||||
|
||||
@@ -8,8 +8,8 @@ import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||
import kr.co.vividnext.sodalive.chat.talk.room.CreateChatRoomRequest
|
||||
import kr.co.vividnext.sodalive.common.UiText
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.common.UiText
|
||||
|
||||
/**
|
||||
* 캐릭터 상세 화면에서 사용하는 ViewModel.
|
||||
@@ -33,12 +33,16 @@ class CharacterDetailViewModel(
|
||||
private val _uiState = MutableLiveData(UiState())
|
||||
val uiState: LiveData<UiState> get() = _uiState
|
||||
|
||||
fun load(characterId: Long) {
|
||||
fun load(characterId: Long, languageCode: String) {
|
||||
_uiState.value = _uiState.value?.copy(isLoading = true, error = null)
|
||||
val token = "Bearer ${SharedPreferenceManager.token}"
|
||||
|
||||
compositeDisposable.add(
|
||||
repository.getCharacterDetail(token = token, characterId = characterId)
|
||||
repository.getCharacterDetail(
|
||||
token = token,
|
||||
characterId = characterId,
|
||||
languageCode = languageCode
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
@@ -46,6 +50,7 @@ class CharacterDetailViewModel(
|
||||
val success = response.success
|
||||
val data = response.data
|
||||
if (success && data != null) {
|
||||
Logger.d("character detail: $data")
|
||||
_uiState.value = UiState(detail = data, isLoading = false, error = null)
|
||||
} else {
|
||||
_uiState.value = UiState(
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package kr.co.vividnext.sodalive.common
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
@@ -38,4 +40,15 @@ object Utils {
|
||||
|
||||
return "https://voiceon.onelink.me/RkTm?$encodedParams"
|
||||
}
|
||||
|
||||
fun getCurrentLanguageCode(context: Context): String {
|
||||
val config = context.resources.configuration
|
||||
val locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
config.locales.get(0)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
config.locale
|
||||
}
|
||||
return locale.language // "ko", "en" 등
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user