Skip to content

Commit

Permalink
Merge pull request #26 from MONEYMONG/epic/moneymong-123-장부
Browse files Browse the repository at this point in the history
Epic/moneymong 123 장부
  • Loading branch information
eunseo0105 authored Aug 12, 2024
2 parents a2cc4c2 + 1d73189 commit f6b0536
Show file tree
Hide file tree
Showing 16 changed files with 327 additions and 39 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.moneymong.moneymong.model.agency.MyAgencyResponse
import com.moneymong.moneymong.model.agency.RegisterAgencyResponse
import com.moneymong.moneymong.model.member.InvitationCodeResponse
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.PATCH
Expand Down Expand Up @@ -49,4 +50,10 @@ interface AgencyApi {
suspend fun reInvitationCode(
@Path("agencyId") agencyId: Long
): Result<InvitationCodeResponse>

//DELETE
@DELETE("api/v1/agencies/{agencyId}")
suspend fun deleteAgency(
@Path("agencyId") agencyId: Int
) : Result<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ interface MemberRemoteDataSource {
suspend fun getMemberLists(agencyId: Long): Result<MemberListResponse>
suspend fun updateMemberAuthor(agencyId : Long, data : UpdateAuthorRequest) : Result<Unit>
suspend fun blockMemberAuthor(agencyId: Long, data : MemberBlockRequest) : Result<Unit>
suspend fun deleteAgency(agencyId: Int) : Result<Unit>

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ class MemberRemoteDataSourceImpl @Inject constructor(
override suspend fun blockMemberAuthor(agencyId: Long, data: MemberBlockRequest): Result<Unit> {
return memberApi.blockMemberAuthor(agencyId, data)
}

override suspend fun deleteAgency(agencyId: Int): Result<Unit> {
return agencyApi.deleteAgency(agencyId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ class MemberRepositoryImpl @Inject constructor(
return memberRemoteDataSource.blockMemberAuthor(agencyId, data)

}

override suspend fun deleteAgency(agencyId: Int): Result<Unit> {
return memberRemoteDataSource.deleteAgency(agencyId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ interface MemberRepository {
suspend fun getMemberLists(agencyId: Long) : Result<MemberListResponse>
suspend fun updateMemberAuthor(agencyId : Long, data : UpdateAuthorRequest) : Result<Unit>
suspend fun blockMemberAuthor(agencyId: Long, data: MemberBlockRequest) : Result<Unit>
suspend fun deleteAgency(agencyId: Int) :Result<Unit>

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.moneymong.moneymong.domain.usecase.member

import com.moneymong.moneymong.domain.repository.member.MemberRepository
import javax.inject.Inject

class DeleteAgencyUseCase @Inject constructor(
private val memberRepository: MemberRepository
) {
suspend operator fun invoke(agencyId: Int) : Result<Unit> {
return memberRepository.deleteAgency(agencyId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,17 @@ fun LedgerScreen(
}
} else {
Box(modifier = modifier.fillMaxSize()) {
MemberScreen(agencyId = state.agencyId)
MemberScreen(
agencyId = state.agencyId,
agencyList = state.agencyList,
onClickItem = {
viewModel.eventEmit(
LedgerSideEffect.LedgerSelectedAgencyChange(
it
)
)
},
changeAgencyList = { viewModel.changeAgencyList(it) })
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.moneymong.moneymong.ledger

import android.util.Log
import androidx.lifecycle.SavedStateHandle
import com.moneymong.moneymong.common.base.BaseViewModel
import com.moneymong.moneymong.common.error.MoneyMongError
Expand All @@ -14,6 +15,7 @@ import com.moneymong.moneymong.domain.usecase.member.MemberListUseCase
import com.moneymong.moneymong.domain.usecase.user.FetchUserIdUseCase
import com.moneymong.moneymong.ledger.navigation.LedgerArgs
import com.moneymong.moneymong.ledger.view.LedgerTransactionType
import com.moneymong.moneymong.model.agency.MyAgencyResponse
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.collectLatest
import org.orbitmvi.orbit.annotation.OrbitExperimental
Expand Down Expand Up @@ -69,6 +71,7 @@ class LedgerViewModel @Inject constructor(
reduce { state.copy(isAgencyExistLoading = true) }
fetchAgencyExistLedgerUseCase(state.agencyId)
.onSuccess {
Log.d("fetchAgencyExistLedger${state.agencyId}",it.toString() )
reduce {
state.copy(
isExistLedger = it,
Expand All @@ -90,18 +93,28 @@ class LedgerViewModel @Inject constructor(
page = 0,
limit = 100
).onSuccess {
Log.d("fetchLedgerTransactionList${state.existAgency}",it.toString() )

reduce {
state.copy(
ledgerTransaction = it,
visibleError = false
)
}
}.onFailure {
reduce {
state.copy(
visibleError = true,
errorMessage = it.message ?: MoneyMongError.UnExpectedError.message
)
if (it.message.equals("장부가 존재하지 않습니다.")) {
reduce { //TODO - 서버 의논 후 변경 예정
state.copy(
visibleError = false,
)
}
} else {
reduce {
state.copy(
visibleError = true,
errorMessage = it.message ?: MoneyMongError.UnExpectedError.message
)
}
}
}.also { reduce { state.copy(isLedgerTransactionLoading = false) } }
}
Expand All @@ -111,6 +124,8 @@ class LedgerViewModel @Inject constructor(
reduce { state.copy(isMyAgencyLoading = true) }
fetchMyAgencyListUseCase()
.onSuccess {
Log.d("fetchMyAgencyList${state.existAgency}",it.toString() )

reduce {
state.copy(
agencyList = it,
Expand Down Expand Up @@ -142,11 +157,20 @@ class LedgerViewModel @Inject constructor(
)
}
}.onFailure {
reduce {
state.copy(
visibleError = true,
errorMessage = it.message ?: MoneyMongError.UnExpectedError.message
)
if (it.message.equals("소속에 가입 후 장부를 사용할 수 있습니다.")) { //TODO - 서버 의논 후 변경 예정
reduce {
state.copy(
visibleError = false
)
}
} else {
reduce {
state.copy(
visibleError = true,
errorMessage = it.message
?: MoneyMongError.UnExpectedError.message
)
}
}
}.also { reduce { state.copy(isAgencyMemberLoading = false) } }
}
Expand Down Expand Up @@ -216,4 +240,13 @@ class LedgerViewModel @Inject constructor(
postDisplayedLedgerOnboardingUseCase(onboardingType = state.onboardingType)
reduce { state.copy(visibleOnboarding = false) }
}
}


fun changeAgencyList(filteredAgencyList: List<MyAgencyResponse>) = intent {
reduce {
state.copy(
agencyList = filteredAgencyList
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupPositionProvider
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.moneymong.moneymong.design_system.theme.Gray10
import com.moneymong.moneymong.design_system.theme.White
import com.moneymong.moneymong.ledger.view.onboarding.popup.LedgerOnboardingPopup
import java.time.LocalDate


Expand Down Expand Up @@ -68,9 +64,7 @@ internal fun LedgerOnboarding(
}
}

Popup(
popupPositionProvider = LedgerPopupPositionProvider()
) {
LedgerOnboardingPopup {
when (currentPage) {
LedgerOnboardingPage.DATE -> {
LedgerOnboardingDatePage(
Expand Down Expand Up @@ -101,20 +95,4 @@ internal fun LedgerOnboarding(
}
}
}
}


private class LedgerPopupPositionProvider : PopupPositionProvider {
override fun calculatePosition(
anchorBounds: IntRect,
windowSize: IntSize,
layoutDirection: LayoutDirection,
popupContentSize: IntSize
): IntOffset {

return IntOffset(
x = 0,
y = 0
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.moneymong.moneymong.ledger.view.onboarding.popup

import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCompositionContext
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.platform.LocalView

@Composable
internal fun LedgerOnboardingPopup(
content: @Composable () -> Unit
) {
val view = LocalView.current
val parentComposition = rememberCompositionContext()
val currentContent by rememberUpdatedState(content)
val popupLayout = remember {
LedgerOnboardingPopupLayout(
composeView = view
).apply {
setContent(parentComposition) {
currentContent()
}
}
}

DisposableEffect(key1 = popupLayout) {
popupLayout.show()

onDispose {
popupLayout.disposeComposition()
popupLayout.dismiss()
}
}
}



Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.moneymong.moneymong.ledger.view.onboarding.popup

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.PixelFormat
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionContext
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.AbstractComposeView
import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner


@SuppressLint("ViewConstructor")
internal class LedgerOnboardingPopupLayout(
private val composeView: View,
) : AbstractComposeView(composeView.context) {

private val windowManager =
composeView.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
private val params = createLayoutParams()
private var content: @Composable () -> Unit by mutableStateOf({})


init {
id = android.R.id.content
setViewTreeLifecycleOwner(composeView.findViewTreeLifecycleOwner())
setViewTreeViewModelStoreOwner(composeView.findViewTreeViewModelStoreOwner())
setViewTreeSavedStateRegistryOwner(composeView.findViewTreeSavedStateRegistryOwner())
}

@Composable
override fun Content() {
content()
}

fun setContent(parent: CompositionContext, content: @Composable () -> Unit) {
setParentCompositionContext(parent)
this.content = content
}

fun show() {
windowManager.addView(this, params)
}

fun dismiss() {
setViewTreeLifecycleOwner(null)
windowManager.removeViewImmediate(this)
}


private fun createLayoutParams(): WindowManager.LayoutParams {
return WindowManager.LayoutParams().apply {
// Start to position the popup in the top left corner, a new position will be calculated
gravity = Gravity.START or Gravity.TOP

// Flags specific to android.widget.PopupWindow
flags = flags and (
WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES or
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
).inv()

// Make the popup window not focusable
flags = flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

// Enables us to intercept outside clicks even when popup is not focusable
flags = flags or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH

type = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL

// Get the Window token from the parent view
token = composeView.applicationWindowToken

// Set the popup window to occupy the entire screen
width = WindowManager.LayoutParams.MATCH_PARENT
height = WindowManager.LayoutParams.MATCH_PARENT

format = PixelFormat.TRANSLUCENT

// accessibilityTitle is not exposed as a public API therefore we set popup window
// title which is used as a fallback by a11y services
title = "LedgerOnboardingPopup"
}
}
}
Loading

0 comments on commit f6b0536

Please sign in to comment.