Skip to content

Commit

Permalink
Merge pull request #243 from boostcampwm-2022/feat/user_location_history
Browse files Browse the repository at this point in the history
사용 위치 기록
  • Loading branch information
mangbaam authored Dec 18, 2022
2 parents ea5b79f + 93abc7a commit c5d1318
Show file tree
Hide file tree
Showing 15 changed files with 111 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import java.util.Date
data class UsageHistoryEntity(
@ColumnInfo(name = "gifticon_id") val gifticonId: String,
@ColumnInfo(name = "date") val date: Date,
@ColumnInfo(name = "address") val address: String,
@ColumnInfo(name = "longitude") val longitude: Double,
@ColumnInfo(name = "latitude") val latitude: Double,
@ColumnInfo(name = "amount") val amount: Int
) {
companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.lighthouse.database.mapper

import com.lighthouse.database.entity.UsageHistoryEntity
import com.lighthouse.domain.VertexLocation
import com.lighthouse.domain.model.UsageHistory

fun UsageHistoryEntity.toUsageHistory(): UsageHistory {
return UsageHistory(
date = date,
address = address,
location = VertexLocation(longitude, latitude),
amount = amount
)
}
Expand All @@ -15,7 +16,8 @@ fun UsageHistory.toUsageHistoryEntity(gifticonId: String): UsageHistoryEntity {
return UsageHistoryEntity(
gifticonId = gifticonId,
date = date,
address = address,
longitude = location?.longitude ?: 0f.toDouble(),
latitude = location?.latitude ?: 0f.toDouble(),
amount = amount
)
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.lighthouse.domain.model

import com.lighthouse.domain.VertexLocation
import java.util.Date

data class UsageHistory(
val date: Date,
val address: String,
val location: VertexLocation?,
val amount: Int
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ package com.lighthouse.domain.usecase
import com.lighthouse.domain.model.UsageHistory
import com.lighthouse.domain.repository.GifticonRepository
import com.lighthouse.domain.util.currentTime
import kotlinx.coroutines.flow.first
import javax.inject.Inject

class UseCashCardGifticonUseCase @Inject constructor(
private val gifticonRepository: GifticonRepository
private val gifticonRepository: GifticonRepository,
private val getUserLocationUseCase: GetUserLocationUseCase
) {

suspend operator fun invoke(gifticonId: String, amount: Int) {
val usageHistory = UsageHistory(currentTime, "광주 광산구 일곡동", amount) // TODO 위치 얻어오기
suspend operator fun invoke(gifticonId: String, amount: Int, hasLocationPermission: Boolean) {
val userLocation = if (hasLocationPermission) getUserLocationUseCase().first() else null
val usageHistory = UsageHistory(currentTime, userLocation, amount)

gifticonRepository.useCashCardGifticon(gifticonId, amount, usageHistory)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ package com.lighthouse.domain.usecase
import com.lighthouse.domain.model.UsageHistory
import com.lighthouse.domain.repository.GifticonRepository
import com.lighthouse.domain.util.currentTime
import kotlinx.coroutines.flow.first
import javax.inject.Inject

class UseGifticonUseCase @Inject constructor(
private val gifticonRepository: GifticonRepository
private val gifticonRepository: GifticonRepository,
private val getUserLocationUseCase: GetUserLocationUseCase
) {
suspend operator fun invoke(gifticonId: String) {
val usageHistory = UsageHistory(currentTime, "광주 광산구 일곡동", 0) // TODO 위치 얻어오기
suspend operator fun invoke(gifticonId: String, hasLocationPermission: Boolean) {
val userLocation = if (hasLocationPermission) getUserLocationUseCase().first() else null
val usageHistory = UsageHistory(currentTime, userLocation, 0)

gifticonRepository.useGifticon(gifticonId, usageHistory)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.fragment.app.activityViewModels
import com.lighthouse.presentation.R
import com.lighthouse.presentation.databinding.FragmentCashCardGifticonInfoBinding
import com.lighthouse.presentation.ui.common.viewBindings
import com.lighthouse.presentation.util.Geography

class CashCardGifticonInfoFragment : Fragment(R.layout.fragment_cash_card_gifticon_info) {
val binding: FragmentCashCardGifticonInfoBinding by viewBindings()
Expand All @@ -16,6 +17,7 @@ class CashCardGifticonInfoFragment : Fragment(R.layout.fragment_cash_card_giftic
super.onViewCreated(view, savedInstanceState)

binding.vm = viewModel
binding.geo = Geography(requireContext())
binding.lifecycleOwner = viewLifecycleOwner
binding.ctfBalance.addOnValueListener {
viewModel.editBalance(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ import com.lighthouse.presentation.ui.detailgifticon.dialog.UseGifticonDialog
import com.lighthouse.presentation.ui.edit.modifygifticon.ModifyGifticonActivity
import com.lighthouse.presentation.ui.security.AuthCallback
import com.lighthouse.presentation.ui.security.AuthManager
import com.lighthouse.presentation.util.permission.LocationPermissionManager
import com.lighthouse.presentation.util.permission.core.permissions
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

Expand Down Expand Up @@ -63,6 +66,8 @@ class GifticonDetailActivity : AppCompatActivity() {
private val chip by lazy { binding.chipScrollDownForUseButton }
private val spinnerDatePicker = SpinnerDatePicker()

private val locationPermission: LocationPermissionManager by permissions()

@Inject
lateinit var authManager: AuthManager
private val biometricLauncher: ActivityResultLauncher<Intent> =
Expand Down Expand Up @@ -104,6 +109,11 @@ class GifticonDetailActivity : AppCompatActivity() {
chip.isVisible = btnMaster.isOnScreen().not()
}
}
repeatOnStarted {
locationPermission.permissionFlow.collectLatest {
viewModel.updateLocationPermission(it)
}
}
repeatOnStarted {
viewModel.event.collect { event ->
handleEvent(event)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ class GifticonDetailViewModel @Inject constructor(
private val _masterButtonLabel = MutableStateFlow<UIText>(UIText.Empty)
val masterButtonLabel = _masterButtonLabel.asStateFlow()

var hasLocationPermission = MutableStateFlow(false)
private set

fun scrollDownForUseButtonClicked() {
event(GifticonDetailEvent.ScrollDownForUseButtonClicked)
}
Expand Down Expand Up @@ -150,11 +153,11 @@ class GifticonDetailViewModel @Inject constructor(
viewModelScope.launch {
if (gifticon.value?.isCashCard == true) {
assert((gifticon.value?.balance ?: 0) >= amountToBeUsed.value)
useCashCardGifticonUseCase(gifticonId, amountToBeUsed.value)
useCashCardGifticonUseCase(gifticonId, amountToBeUsed.value, hasLocationPermission.value)
amountToBeUsed.value = 0
event(GifticonDetailEvent.UseGifticonComplete)
} else {
useGifticonUseCase(gifticonId)
useGifticonUseCase(gifticonId, hasLocationPermission.value)
event(GifticonDetailEvent.UseGifticonComplete)
}
}
Expand Down Expand Up @@ -190,6 +193,10 @@ class GifticonDetailViewModel @Inject constructor(
}
}

fun updateLocationPermission(isLocationPermission: Boolean) {
hasLocationPermission.value = isLocationPermission
}

private fun switchMode(mode: GifticonDetailMode) {
_mode.value = mode
_scrollDownChipLabel.value = when (_mode.value) {
Expand All @@ -199,8 +206,8 @@ class GifticonDetailViewModel @Inject constructor(
}
_masterButtonLabel.value = when (_mode.value) {
GifticonDetailMode.UNUSED -> UIText.StringResource(R.string.gifticon_detail_unused_mode_button_text)
GifticonDetailMode.EDIT -> UIText.StringResource(R.string.gifticon_detail_used_mode_button_text)
GifticonDetailMode.USED -> UIText.StringResource(R.string.gifticon_detail_edit_mode_button_text)
GifticonDetailMode.EDIT -> UIText.StringResource(R.string.gifticon_detail_edit_mode_button_text)
GifticonDetailMode.USED -> UIText.StringResource(R.string.gifticon_detail_used_mode_button_text)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.fragment.app.activityViewModels
import com.lighthouse.presentation.R
import com.lighthouse.presentation.databinding.FragmentStandardGifticonInfoBinding
import com.lighthouse.presentation.ui.common.viewBindings
import com.lighthouse.presentation.util.Geography

class StandardGifticonInfoFragment : Fragment(R.layout.fragment_standard_gifticon_info) {
private val binding: FragmentStandardGifticonInfoBinding by viewBindings()
Expand All @@ -15,6 +16,7 @@ class StandardGifticonInfoFragment : Fragment(R.layout.fragment_standard_giftico
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.vm = viewModel
binding.geo = Geography(requireContext())
binding.lifecycleOwner = viewLifecycleOwner
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import com.lighthouse.domain.model.UsageHistory
import com.lighthouse.presentation.R
import com.lighthouse.presentation.adapter.BindableListAdapter
import com.lighthouse.presentation.databinding.ItemUsageHistoryBinding
import com.lighthouse.presentation.util.Geography

class UsageHistoryAdapter : BindableListAdapter<UsageHistory, UsageHistoryAdapter.UsageHistoryViewHolder>(diffUtil) {

class UsageHistoryViewHolder(private val binding: ItemUsageHistoryBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(usageHistory: UsageHistory) {
binding.geo = Geography(binding.root.context)
binding.usage = usageHistory
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class GifticonListViewModel @Inject constructor(

fun completeUsage(gifticon: GifticonUIModel) {
viewModelScope.launch {
useGifticonUseCase(gifticon.id)
useGifticonUseCase(gifticon.id, false)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.lighthouse.presentation.util

import android.content.Context
import android.location.Address
import android.location.Geocoder
import android.os.Build
import com.lighthouse.domain.VertexLocation
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class Geography @Inject constructor(@ApplicationContext private val context: Context) {

// 위도 경도로 주소 구하는 Reverse-GeoCoding
fun getAddress(position: VertexLocation?): String {
position ?: return ""

val geoCoder = Geocoder(context)
var addr = "-"

// GRPC 오류 대응
try {
var location: Address? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
geoCoder.getFromLocation(position.latitude, position.longitude, 1) {
location = it.first()
}
} else {
location = geoCoder.getFromLocation(position.latitude, position.longitude, 1)?.first()
}
addr = listOfNotNull(
location?.adminArea,
location?.subAdminArea,
location?.locality,
location?.subLocality,
location?.thoroughfare
).joinToString(" ")
} catch (e: Exception) {
e.printStackTrace()
}
return addr
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
name="vm"
type="com.lighthouse.presentation.ui.detailgifticon.GifticonDetailViewModel" />

<variable
name="geo"
type="com.lighthouse.presentation.util.Geography" />

<import
alias="mode"
type="com.lighthouse.presentation.ui.detailgifticon.GifticonDetailMode" />
Expand Down Expand Up @@ -169,7 +173,7 @@
android:layout_marginTop="4dp"
android:ellipsize="end"
android:maxLines="1"
android:text="@{vm.latestUsageHistory.address}"
android:text="@{geo.getAddress(vm.latestUsageHistory.location)}"
app:layout_constraintEnd_toStartOf="@id/iv_show_all_used_info_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_used_address_label"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
name="vm"
type="com.lighthouse.presentation.ui.detailgifticon.GifticonDetailViewModel" />

<variable
name="geo"
type="com.lighthouse.presentation.util.Geography" />

<import
alias="mode"
type="com.lighthouse.presentation.ui.detailgifticon.GifticonDetailMode" />
Expand Down Expand Up @@ -41,8 +45,8 @@
android:inputType="textAutoComplete"
android:maxLines="1"
android:minWidth="100dp"
android:paddingEnd="16dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@{vm.tempGifticon.name ?? vm.gifticon.name}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_product_name_label"
Expand Down Expand Up @@ -72,8 +76,8 @@
android:inputType="textAutoComplete"
android:maxLines="1"
android:minWidth="100dp"
android:paddingEnd="16dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
android:text="@{vm.tempGifticon.brand ?? vm.gifticon.brand}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_brand_label"
Expand Down Expand Up @@ -105,8 +109,8 @@
android:enabled="@{vm.mode==mode.EDIT}"
android:minWidth="100dp"
android:onClick="@{() -> vm.expireDateClicked()}"
android:paddingEnd="16dp"
android:paddingStart="0dp"
android:paddingEnd="16dp"
app:dateFormat="@{vm.tempGifticon.expireAt ?? vm.gifticon.expireAt}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_expire_at_label"
Expand Down Expand Up @@ -138,7 +142,7 @@
android:layout_marginTop="4dp"
android:ellipsize="end"
android:maxLines="1"
android:text="@{vm.latestUsageHistory.address}"
android:text="@{geo.getAddress(vm.latestUsageHistory.location)}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_used_address_label"
Expand Down
6 changes: 5 additions & 1 deletion presentation/src/main/res/layout/item_usage_history.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
<variable
name="usage"
type="com.lighthouse.domain.model.UsageHistory" />

<variable
name="geo"
type="com.lighthouse.presentation.util.Geography" />
</data>

<LinearLayout
Expand Down Expand Up @@ -35,7 +39,7 @@
android:gravity="center"
android:maxLines="2"
android:paddingHorizontal="2dp"
android:text="@{usage.address}"
android:text="@{geo.getAddress(usage.location)}"
tools:text="서울시 용산구" />

<TextView
Expand Down

0 comments on commit c5d1318

Please sign in to comment.