Skip to content

Commit

Permalink
Merge branch 'dev/and' into feat/and/go-to-naver-shop
Browse files Browse the repository at this point in the history
  • Loading branch information
Taewan-P authored Feb 5, 2024
2 parents e742a93 + 0e6221c commit 350e639
Show file tree
Hide file tree
Showing 38 changed files with 1,426 additions and 167 deletions.
11 changes: 6 additions & 5 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_priceguard_notification" />

<activity
android:name=".ui.additem.link.LinkHelperWebViewActivity"
android:exported="false" />
<activity
android:name=".ui.splash.SplashScreenActivity"
android:exported="true">
Expand Down Expand Up @@ -78,6 +74,12 @@
<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
android:theme="@style/Theme.PriceGuard.WithActionBar" />
<activity
android:name=".ui.additem.link.LinkHelperWebViewActivity"
android:exported="false" />
<activity
android:name=".ui.home.mypage.DeleteAccountActivity"
android:exported="false" />

<service
android:name=".service.PriceGuardFirebaseMessagingService"
Expand All @@ -91,7 +93,6 @@
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />

</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package app.priceguard.data.dto.deleteaccount

import kotlinx.serialization.Serializable

@Serializable
data class DeleteAccountRequest(
val email: String,
val password: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package app.priceguard.data.dto.deleteaccount

import kotlinx.serialization.Serializable

@Serializable
data class DeleteAccountResponse(
val statusCode: Int,
val message: String
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package app.priceguard.data.network

import app.priceguard.data.dto.deleteaccount.DeleteAccountRequest
import app.priceguard.data.dto.deleteaccount.DeleteAccountResponse
import app.priceguard.data.dto.firebase.FirebaseTokenUpdateRequest
import app.priceguard.data.dto.firebase.FirebaseTokenUpdateResponse
import app.priceguard.data.dto.login.LoginRequest
Expand All @@ -24,6 +26,11 @@ interface UserAPI {
@Body request: SignupRequest
): Response<SignupResponse>

@POST("remove")
suspend fun deleteAccount(
@Body request: DeleteAccountRequest
): Response<DeleteAccountResponse>

@PUT("firebase/token")
suspend fun updateFirebaseToken(
@Header("Authorization") authToken: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ interface AuthRepository {
suspend fun signUp(email: String, userName: String, password: String): RepositoryResult<SignupResult, AuthErrorState>

suspend fun login(email: String, password: String): RepositoryResult<LoginResult, AuthErrorState>

suspend fun deleteAccount(email: String, password: String): RepositoryResult<Boolean, AuthErrorState>
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package app.priceguard.data.repository.auth

import app.priceguard.data.dto.deleteaccount.DeleteAccountRequest
import app.priceguard.data.dto.login.LoginRequest
import app.priceguard.data.dto.signup.SignupRequest
import app.priceguard.data.network.UserAPI
Expand Down Expand Up @@ -73,4 +74,20 @@ class AuthRepositoryImpl @Inject constructor(private val userAPI: UserAPI) : Aut
}
}
}

override suspend fun deleteAccount(email: String, password: String): RepositoryResult<Boolean, AuthErrorState> {
val response = getApiResult {
userAPI.deleteAccount(DeleteAccountRequest(email, password))
}

return when (response) {
is APIResult.Success -> {
RepositoryResult.Success(true)
}

is APIResult.Error -> {
handleError(response.code)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package app.priceguard.ui.additem.setprice

import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.viewModels
import app.priceguard.R
import app.priceguard.databinding.FragmentTargetPriceDialogBinding
import app.priceguard.ui.util.lifecycle.repeatOnStarted
import app.priceguard.ui.util.setTextColorWithEnabled
import com.google.android.material.dialog.MaterialAlertDialogBuilder

class SetTargetPriceDialogFragment : DialogFragment() {

private var _binding: FragmentTargetPriceDialogBinding? = null
private val binding get() = _binding!!

private val viewModel: SetTargetPriceDialogViewModel by viewModels()

private var resultListener: OnDialogResultListener? = null

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
_binding = FragmentTargetPriceDialogBinding.inflate(requireActivity().layoutInflater)
val view = binding.root

val title = arguments?.getString("title") ?: ""

val dialogBuilder = MaterialAlertDialogBuilder(
requireActivity(),
R.style.ThemeOverlay_App_MaterialAlertDialog
).apply {
setTitle(title)
setView(view)
setNegativeButton(R.string.cancel) { _, _ -> dismiss() }
setPositiveButton(R.string.confirm) { _, _ ->
resultListener?.onDialogResult(viewModel.state.value.targetPrice.toInt())
dismiss()
}
}
val dialog = dialogBuilder.create()

repeatOnStarted {
viewModel.state.collect { state ->
viewModel.updateTextChangedEnabled(false)
binding.etTargetPriceDialog.setText(
getString(R.string.won, getString(R.string.comma_number, state.targetPrice))
)
val positiveButton = dialog.getButton(Dialog.BUTTON_POSITIVE)
positiveButton.isEnabled = !state.isErrorMessageVisible
positiveButton.setTextColorWithEnabled()

viewModel.updateTextChangedEnabled(true)
}
}

return dialog
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreateView(inflater, container, savedInstanceState)

binding.viewModel = viewModel
binding.lifecycleOwner = viewLifecycleOwner

initListener()

val price = arguments?.getInt("price") ?: 0
viewModel.updateTargetPrice(price.toLong())

return binding.root
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

private fun initListener() {
binding.etTargetPriceDialog.addTextChangedListener {
binding.etTargetPriceDialog.setSelection(it.toString().length - 1)

val price = extractAndConvertToInteger(it.toString())

if (viewModel.state.value.isTextChanged) {
if (price > MAX_TARGET_PRICE) {
viewModel.updateErrorMessageVisible(true)
} else {
viewModel.updateErrorMessageVisible(false)
}
viewModel.updateTargetPrice(price)
}
}

binding.etTargetPriceDialog.setOnClickListener {
binding.etTargetPriceDialog.setSelection(binding.etTargetPriceDialog.text.toString().length - 1)
}
}

private fun extractAndConvertToInteger(text: String): Long {
val digits = text.filter { it.isDigit() }
return (digits.toLongOrNull() ?: 0).coerceIn(0, MAX_TARGET_PRICE * 10 - 1)
}

fun setOnDialogResultListener(listener: OnDialogResultListener) {
resultListener = listener
}

interface OnDialogResultListener {
fun onDialogResult(result: Int)
}

companion object {
const val MAX_TARGET_PRICE = 1_000_000_000L
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package app.priceguard.ui.additem.setprice

import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow

class SetTargetPriceDialogViewModel : ViewModel() {

data class SetTargetPriceDialogState(
val targetPrice: Long = 0,
val isTextChanged: Boolean = false,
val isErrorMessageVisible: Boolean = false
)

private val _state = MutableStateFlow(SetTargetPriceDialogState())
val state = _state.asStateFlow()

fun updateTargetPrice(price: Long) {
_state.value = _state.value.copy(targetPrice = price)
}

fun updateTextChangedEnabled(isEnabled: Boolean) {
_state.value = _state.value.copy(isTextChanged = isEnabled)
}

fun updateErrorMessageVisible(isEnabled: Boolean) {
_state.value = _state.value.copy(isErrorMessageVisible = isEnabled)
}
}
Loading

0 comments on commit 350e639

Please sign in to comment.