Skip to content

Commit

Permalink
Merge pull request #80 from YAPP-Github/feature/MZ-145-export
Browse files Browse the repository at this point in the history
Feature/mz 145 엑셀 파일 다운로드
  • Loading branch information
yangsooplus authored Jan 21, 2024
2 parents 688ae13 + d86f0d7 commit 2df6410
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 3 deletions.
2 changes: 2 additions & 0 deletions core/ui/src/main/java/com/susu/core/ui/Consts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ val alignList
const val USER_NAME_MAX_LENGTH = 10
val nameRegex = Regex("[a-zA-Z가-힣]{0,10}")

const val INTENT_ACTION_DOWNLOAD_COMPLETE = "android.intent.action.DOWNLOAD_COMPLETE"

enum class SnsProviders(
val path: String,
@StringRes val nameId: Int,
Expand Down
7 changes: 7 additions & 0 deletions data/src/main/java/com/susu/data/data/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.susu.data.data.di

import com.susu.data.data.repository.CategoryConfigRepositoryImpl
import com.susu.data.data.repository.ExcelRepositoryImpl
import com.susu.data.data.repository.LedgerRecentSearchRepositoryImpl
import com.susu.data.data.repository.LedgerRepositoryImpl
import com.susu.data.data.repository.LoginRepositoryImpl
Expand All @@ -9,6 +10,7 @@ import com.susu.data.data.repository.TermRepositoryImpl
import com.susu.data.data.repository.TokenRepositoryImpl
import com.susu.data.data.repository.UserRepositoryImpl
import com.susu.domain.repository.CategoryConfigRepository
import com.susu.domain.repository.ExcelRepository
import com.susu.domain.repository.LedgerRecentSearchRepository
import com.susu.domain.repository.LedgerRepository
import com.susu.domain.repository.LoginRepository
Expand Down Expand Up @@ -64,4 +66,9 @@ abstract class RepositoryModule {
abstract fun bindUserRepository(
userRepositoryImpl: UserRepositoryImpl,
): UserRepository

@Binds
abstract fun bindExcelRepository(
excelRepositoryImpl: ExcelRepositoryImpl,
): ExcelRepository
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.susu.data.data.repository

import android.app.DownloadManager
import android.os.Environment
import androidx.core.net.toUri
import com.susu.core.model.exception.UnknownException
import com.susu.domain.repository.ExcelRepository
import com.susu.domain.repository.TokenRepository
import kotlinx.coroutines.flow.firstOrNull
import javax.inject.Inject

class ExcelRepositoryImpl @Inject constructor(
private val downloadManager: DownloadManager,
private val tokenRepository: TokenRepository,
) : ExcelRepository {
override suspend fun downloadEnvelopExcel(): Long {
val token = tokenRepository.getAccessToken().firstOrNull() ?: throw UnknownException()

val request = DownloadManager.Request(url.toUri())
.setMimeType(mimeType)
.setAllowedOverMetered(true)
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
.setTitle(downloaderName)
.addRequestHeader(headerTokenName, token)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)

return downloadManager.enqueue(request)
}

companion object {
private const val url = "https://api.oksusu.site/api/v1/excel/all-envelopes"
private const val mimeType = "application/vnd.ms-excel"
private const val downloaderName = "수수"
private const val headerTokenName = "X-SUSU-AUTH-TOKEN"
private const val fileName = "수수_기록.xlsx"
}
}
21 changes: 21 additions & 0 deletions data/src/main/java/com/susu/data/remote/di/ExcelModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.susu.data.remote.di

import android.app.DownloadManager
import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object ExcelModule {

@Provides
@Singleton
fun providesDownloadManager(@ApplicationContext context: Context): DownloadManager {
return context.getSystemService(DownloadManager::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.susu.domain.repository

interface ExcelRepository {
suspend fun downloadEnvelopExcel(): Long
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.susu.domain.usecase.mypage

import com.susu.core.common.runCatchingIgnoreCancelled
import com.susu.domain.repository.ExcelRepository
import javax.inject.Inject

class DownloadExcelUseCase @Inject constructor(
private val excelRepository: ExcelRepository,
) {
suspend operator fun invoke() = runCatchingIgnoreCancelled {
excelRepository.downloadEnvelopExcel()
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.susu.feature.mypage.main

import android.os.Environment
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
Expand Down Expand Up @@ -78,7 +79,7 @@ fun MyPageDefaultRoute(
onShowDialog(
DialogToken(
title = context.getString(com.susu.feature.mypage.R.string.dialog_export_title),
text = context.getString(com.susu.feature.mypage.R.string.dialog_export_detail),
text = context.getString(com.susu.feature.mypage.R.string.dialog_export_detail, Environment.DIRECTORY_DOWNLOADS),
dismissText = context.getString(R.string.word_cancel),
confirmText = context.getString(com.susu.feature.mypage.R.string.dialog_export_confirm),
onConfirmRequest = viewModel::export,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.kakao.sdk.auth.TokenManagerProvider
import com.kakao.sdk.user.UserApiClient
import com.susu.core.model.exception.UserNotFoundException
import com.susu.core.ui.base.BaseViewModel
import com.susu.domain.usecase.mypage.DownloadExcelUseCase
import com.susu.domain.usecase.mypage.GetUserUseCase
import com.susu.domain.usecase.mypage.LogoutUseCase
import com.susu.domain.usecase.mypage.WithdrawUseCase
Expand All @@ -17,6 +18,7 @@ class MyPageViewModel @Inject constructor(
private val logoutUseCase: LogoutUseCase,
private val withdrawUseCase: WithdrawUseCase,
private val getUserUseCase: GetUserUseCase,
private val downloadExcelUseCase: DownloadExcelUseCase,
) : BaseViewModel<MyPageState, MyPageEffect>(MyPageState()) {

init {
Expand Down Expand Up @@ -72,6 +74,10 @@ class MyPageViewModel @Inject constructor(
}

fun export() {
postSideEffect(MyPageEffect.ShowExportSuccessSnackbar)
viewModelScope.launch {
downloadExcelUseCase().onFailure {
postSideEffect(MyPageEffect.HandleException(it, ::export))
}
}
}
}
2 changes: 1 addition & 1 deletion feature/mypage/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<string name="dialog_logout_title">로그아웃 할까요?</string>
<string name="dialog_logout_confirm">로그아웃</string>
<string name="dialog_export_title">엑셀로 내보낼까요?</string>
<string name="dialog_export_detail">모든 기록을 엑셀로 저장해요. 파일은 (경로)에서 확인할 수 있어요.</string>
<string name="dialog_export_detail">모든 기록을 엑셀로 저장해요. 파일은 %s에서 확인할 수 있어요.</string>
<string name="dialog_export_confirm">내보내기</string>
<string name="dialog_withdraw_title">정말 탈퇴하시겠어요?</string>
<string name="dialog_withdraw_detail">계정 정보와 모든 기록이 삭제되며 다시 복구할 수 없어요</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package com.susu.feature.navigator

import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
Expand All @@ -11,9 +16,12 @@ import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.ui.Modifier
import androidx.core.content.ContextCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.WindowCompat
import com.susu.core.designsystem.theme.SusuTheme
import com.susu.core.ui.INTENT_ACTION_DOWNLOAD_COMPLETE
import com.susu.core.ui.SnackbarToken
import com.susu.feature.loginsignup.social.KakaoLoginHelper
import dagger.hilt.android.AndroidEntryPoint

Expand All @@ -24,6 +32,8 @@ class MainActivity : ComponentActivity() {
private val uiState
get() = viewModel.uiState.value

private lateinit var broadcastReceiver: BroadcastReceiver

override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
super.onCreate(savedInstanceState)
Expand All @@ -45,6 +55,24 @@ class MainActivity : ComponentActivity() {

WindowCompat.setDecorFitsSystemWindows(window, false)

broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
if (intent?.action == INTENT_ACTION_DOWNLOAD_COMPLETE) {
val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1L)
if (id != -1L) {
viewModel.onShowSnackbar(SnackbarToken(message = context.getString(com.susu.feature.mypage.R.string.snackbar_success_export)))
}
}
}
}

ContextCompat.registerReceiver(
this,
broadcastReceiver,
IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE),
ContextCompat.RECEIVER_EXPORTED,
)

setContent {
SusuTheme {
MainScreen(
Expand All @@ -60,4 +88,9 @@ class MainActivity : ComponentActivity() {
}
}
}

override fun onDestroy() {
super.onDestroy()
unregisterReceiver(broadcastReceiver)
}
}

0 comments on commit 2df6410

Please sign in to comment.