From 805b5ee494ff71883d7c019f7ab7b00bad92fafa Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Wed, 22 Nov 2023 19:20:07 +0900 Subject: [PATCH] :bug: Fix toast error for symbol creation --- .../symbolcreation/SymbolCreationScreen.kt | 14 +++++++---- .../speechbuddy/data/local/SymbolDao.kt | 2 +- .../repository/SymbolRepository.kt | 21 ++++++++++------ .../example/speechbuddy/utils/Constants.kt | 2 ++ .../viewmodel/SymbolCreationViewModel.kt | 24 +++++++++---------- 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolcreation/SymbolCreationScreen.kt b/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolcreation/SymbolCreationScreen.kt index 06362902..45296191 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolcreation/SymbolCreationScreen.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/compose/symbolcreation/SymbolCreationScreen.kt @@ -38,6 +38,7 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState @@ -54,8 +55,8 @@ import androidx.hilt.navigation.compose.hiltViewModel import com.example.speechbuddy.R import com.example.speechbuddy.compose.utils.ButtonUi import com.example.speechbuddy.compose.utils.TextFieldUi -import com.example.speechbuddy.compose.utils.TopAppBarUi import com.example.speechbuddy.compose.utils.TitleUi +import com.example.speechbuddy.compose.utils.TopAppBarUi import com.example.speechbuddy.domain.models.Category import com.example.speechbuddy.ui.models.SymbolCreationErrorType import com.example.speechbuddy.ui.models.SymbolCreationUiState @@ -87,6 +88,13 @@ fun SymbolCreationScreen( viewModel.setPhotoInputUri(uri, context) } + if (creationResultMessage != null) { + LaunchedEffect(key1 = creationResultMessage) { + val toastMessage = context.resources.getString(creationResultMessage!!) + Toast.makeText(context, toastMessage, Toast.LENGTH_SHORT).show() + } + } + Surface( modifier = modifier.fillMaxSize() ) { @@ -158,10 +166,6 @@ fun SymbolCreationScreen( } } } - if (creationResultMessage != null) { - val toastMessage = stringResource(id = creationResultMessage!!) - Toast.makeText(context, toastMessage, Toast.LENGTH_SHORT).show() - } } @Composable diff --git a/frontend/app/src/main/java/com/example/speechbuddy/data/local/SymbolDao.kt b/frontend/app/src/main/java/com/example/speechbuddy/data/local/SymbolDao.kt index eae93a07..350e7eb1 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/data/local/SymbolDao.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/data/local/SymbolDao.kt @@ -18,7 +18,7 @@ interface SymbolDao { fun getSymbols(): Flow> @Query("SELECT * FROM symbols ORDER BY id DESC LIMIT 1") - fun getLastSymbol(): Flow> + fun getLastSymbol(): Flow @Query("SELECT * FROM symbols WHERE isFavorite = 1") fun getFavoriteSymbols(): Flow> diff --git a/frontend/app/src/main/java/com/example/speechbuddy/repository/SymbolRepository.kt b/frontend/app/src/main/java/com/example/speechbuddy/repository/SymbolRepository.kt index 5f0b4a47..752d3154 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/repository/SymbolRepository.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/repository/SymbolRepository.kt @@ -6,7 +6,6 @@ import com.example.speechbuddy.data.local.models.CategoryMapper import com.example.speechbuddy.data.local.models.SymbolEntity import com.example.speechbuddy.data.local.models.SymbolMapper import com.example.speechbuddy.data.remote.MySymbolRemoteSource -import com.example.speechbuddy.utils.ResponseHandler import com.example.speechbuddy.data.remote.models.MySymbolDtoMapper import com.example.speechbuddy.domain.SessionManager import com.example.speechbuddy.domain.models.Category @@ -15,6 +14,7 @@ import com.example.speechbuddy.domain.models.MySymbol import com.example.speechbuddy.domain.models.Symbol import com.example.speechbuddy.utils.Resource import com.example.speechbuddy.utils.ResponseCode +import com.example.speechbuddy.utils.ResponseHandler import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map @@ -37,17 +37,12 @@ class SymbolRepository @Inject constructor( private val categoryMapper: CategoryMapper ) { - fun getSymbols(query: String) = if (query.isBlank()) getAllSymbols() else symbolDao.getSymbolsByQuery(query).map { symbolEntities -> symbolEntities.map { symbolEntity -> symbolMapper.mapToDomainModel(symbolEntity) } } - fun getLastSymbol() = symbolDao.getLastSymbol().map { symbolEntities -> - symbolEntities.first().let { symbolEntity -> symbolMapper.mapToDomainModel(symbolEntity) } - } - fun getCategories(query: String) = if (query.isBlank()) getAllCategories() else categoryDao.getCategoriesByQuery(query).map { categoryEntities -> @@ -101,6 +96,13 @@ class SymbolRepository @Inject constructor( symbolDao.updateSymbol(symbolEntity) } + fun getNextSymbolId() = + symbolDao.getLastSymbol().map { symbol -> symbol.id +1 } + + fun clearAllMySymbols() { + /* TODO: 내가 만든 상징들 모두 삭제 */ + } + suspend fun insertSymbol(symbol: Symbol) { val symbolEntity = symbolMapper.mapFromDomainModel(symbol) symbolDao.insertSymbol(symbolEntity) @@ -111,7 +113,12 @@ class SymbolRepository @Inject constructor( categoryId: Int, image: MultipartBody.Part ): Flow> { - return mySymbolRemoteSource.createSymbolBackup(getAuthHeader(), symbolText, categoryId, image) + return mySymbolRemoteSource.createSymbolBackup( + getAuthHeader(), + symbolText, + categoryId, + image + ) .map { response -> if (response.isSuccessful && response.code() == ResponseCode.SUCCESS.value) { response.body()?.let { mySymbolDto -> diff --git a/frontend/app/src/main/java/com/example/speechbuddy/utils/Constants.kt b/frontend/app/src/main/java/com/example/speechbuddy/utils/Constants.kt index e1fc424e..3b8d57a7 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/utils/Constants.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/utils/Constants.kt @@ -20,5 +20,7 @@ class Constants { const val CODE_LENGTH = 6 const val MAXIMUM_LINES_FOR_SYMBOL_TEXT = 2 const val MAXIMUM_SYMBOL_TEXT_LENGTH = 20 + + const val DEFAULT_SYMBOL_COUNT = 500 } } \ No newline at end of file diff --git a/frontend/app/src/main/java/com/example/speechbuddy/viewmodel/SymbolCreationViewModel.kt b/frontend/app/src/main/java/com/example/speechbuddy/viewmodel/SymbolCreationViewModel.kt index e03a3b97..3ae96ae4 100644 --- a/frontend/app/src/main/java/com/example/speechbuddy/viewmodel/SymbolCreationViewModel.kt +++ b/frontend/app/src/main/java/com/example/speechbuddy/viewmodel/SymbolCreationViewModel.kt @@ -24,19 +24,16 @@ import com.example.speechbuddy.repository.WeightTableRepository import com.example.speechbuddy.ui.models.SymbolCreationError import com.example.speechbuddy.ui.models.SymbolCreationErrorType import com.example.speechbuddy.ui.models.SymbolCreationUiState +import com.example.speechbuddy.utils.Constants.Companion.DEFAULT_SYMBOL_COUNT import com.example.speechbuddy.utils.Status import com.example.speechbuddy.utils.isValidSymbolText import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import okhttp3.MediaType.Companion.toMediaType import okhttp3.MultipartBody import okhttp3.RequestBody.Companion.asRequestBody @@ -134,6 +131,7 @@ class SymbolCreationViewModel @Inject internal constructor( } } } + private fun clearInput() { symbolTextInput = "" categoryInput = null @@ -223,11 +221,10 @@ class SymbolCreationViewModel @Inject internal constructor( } } else { // If guest-mode - if(sessionManager.userId.value ==-1){ + if (sessionManager.userId.value == GUEST) { viewModelScope.launch { - val lastSymbol = repository.getLastSymbol().first() - val symbolId = lastSymbol.id+1 - val fileName = "symbol_${ symbolId }" + val symbolId = repository.getNextSymbolId().first() + val fileName = "symbol_${symbolId}" bitmapToFile(context, photoInputBitmap!!, fileName) val symbol = Symbol( @@ -247,13 +244,12 @@ class SymbolCreationViewModel @Inject internal constructor( // Notify user that the creation was successful _creationResultMessage.postValue(R.string.create_symbol_success) } - } - else { // If login-mode + } else { // If login-mode // file processing val tempFileName = "symbol_${System.currentTimeMillis()}" val imageFile = bitmapToFile(context, photoInputBitmap!!, tempFileName) val imagePart = fileToMultipartBodyPart(imageFile, "image") - viewModelScope.launch() { + viewModelScope.launch { repository.createSymbolBackup( symbolText = symbolTextInput, categoryId = categoryInput!!.id, @@ -262,7 +258,7 @@ class SymbolCreationViewModel @Inject internal constructor( if (resource.status == Status.SUCCESS) { // Store new symbol in local db val symbolId = resource.data!!.id - val imageUrl = resource.data!!.imageUrl + val imageUrl = resource.data.imageUrl val symbol = Symbol( id = symbolId!!, text = symbolTextInput, @@ -302,4 +298,8 @@ class SymbolCreationViewModel @Inject internal constructor( } } } + + companion object { + const val GUEST = -1 + } } \ No newline at end of file