Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/1.1.1 #8

Merged
merged 8 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,4 @@ fabric.properties
/report

# End of https://www.toptal.com/developers/gitignore/api/androidstudio,kotlin
/Susu
2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ android {

defaultConfig {
applicationId = "com.oksusu.susu"
versionCode = 7
versionName = "1.0.4"
versionCode = 10
versionName = "1.1.1"
buildConfigField("String", "KAKAO_APP_KEY", getApiKey("KAKAO_APP_KEY"))
manifestPlaceholders["KAKAO_APP_KEY"] = "kakao${getApiKey("KAKAO_REDIRECT_KEY")}"
}
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@
android:scheme="${KAKAO_APP_KEY}" />
</intent-filter>
</activity>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.oksusu.susu.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>

</manifest>
6 changes: 6 additions & 0 deletions app/src/main/res/xml/file_paths.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="downloads"
path="Download/" />
</paths>
40 changes: 40 additions & 0 deletions core/android/src/main/java/com/susu/core/android/FileUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.susu.core.android

import android.app.DownloadManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.content.ContextCompat.getSystemService
import androidx.core.content.FileProvider
import java.io.File

object FileUtils {
fun openFile(context: Context, downloadId: Long) {
val query = DownloadManager.Query().apply {
setFilterById(downloadId) // 다운로드 ID로 파일 조회
}
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager

val cursor = downloadManager.query(query)
cursor?.let {
if (it.moveToFirst()) {
val columnIndex = it.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)
val fileUri = it.getString(columnIndex)
val filePath = Uri.parse(fileUri)

val contentUri = FileProvider.getUriForFile(
context,
"${context.packageName}.fileprovider",
File(filePath.path)
)

val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(contentUri, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
context.startActivity(intent)
}
it.close()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class ExcelRepositoryImpl @Inject constructor(
}

companion object {
private const val url = "https://api.oksusu.site/api/v1/excel/all-envelopes"
private const val url = "https://api.oksusu.biz/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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,8 @@ class FriendRepositoryImpl @Inject constructor(
customRelation = customRelation,
),
).getOrThrow()

override suspend fun deleteFriends(ids: List<Long>) {
friendService.deleteFriends(ids = ids).getOrThrow()
}
}
6 changes: 6 additions & 0 deletions data/src/main/java/com/susu/data/remote/api/FriendService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.susu.data.remote.model.response.FriendResponse
import com.susu.data.remote.model.response.FriendSearchListResponse
import com.susu.data.remote.retrofit.ApiResult
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.PUT
Expand All @@ -28,4 +29,9 @@ interface FriendService {
@Path("id") id: Long,
@Body friendRequest: FriendRequest,
): ApiResult<Unit>

@DELETE("friends")
suspend fun deleteFriends(
@Query("ids") ids: List<Long>,
): ApiResult<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
object NetworkModule {

private const val BASE_URL = "https://api.oksusu.site/api/v1/"
private const val BASE_URL = "https://api.oksusu.biz/api/v1/"

@Singleton
@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ interface FriendRepository {
relationshipId: Long,
customRelation: String? = null,
)

suspend fun deleteFriends(
ids: List<Long>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.susu.domain.usecase.friend

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

class DeleteFriendUseCase @Inject constructor(
private val friendRepository: FriendRepository
) {
suspend operator fun invoke(friendId: Long) = runCatchingIgnoreCancelled {
friendRepository.deleteFriends(ids = listOf(friendId))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ sealed interface SignUpEffect : SideEffect {
data class SignUpState(
val isLoading: Boolean = false,
val currentStep: SignUpStep = SignUpStep.TERMS,
val localTermAgreed: Boolean = false,
val agreedTerms: PersistentSet<Int> = persistentSetOf(),
val name: String = "",
val isNameValid: Boolean = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ fun SignUpRoute(
uiState = uiState,
termState = termState,
isNextStepActive = when (uiState.currentStep) {
SignUpStep.TERMS -> uiState.agreedTerms.containsAll(termState.terms.filter { it.isEssential }.map { it.id })
SignUpStep.TERMS -> uiState.localTermAgreed && uiState.agreedTerms.containsAll(termState.terms.filter { it.isEssential }.map { it.id })
SignUpStep.TERM_DETAIL -> true
SignUpStep.NAME -> uiState.isNameValid && uiState.name.isNotEmpty()
SignUpStep.ADDITIONAL -> true
Expand Down Expand Up @@ -130,6 +130,7 @@ fun SignUpRoute(
descriptionText = targetState.description?.let { stringResource(id = it) } ?: "",
terms = termState.terms,
agreedTerms = uiState.agreedTerms.toPersistentList(),
localTermAgreed = uiState.localTermAgreed,
onDetailClick = {
termViewModel.updateCurrentTerm(it)
viewModel.goTermDetail()
Expand All @@ -144,6 +145,9 @@ fun SignUpRoute(
onTermChecked = { agree, id ->
if (agree) viewModel.agreeTerm(id) else viewModel.disagreeTerm(id)
},
onLocalTermChecked = { agree ->
viewModel.updateLocalTermAgreed(agree)
}
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,16 @@ class SignUpViewModel @Inject constructor(
intent { copy(agreedTerms = agreedTerms.remove(termId)) }
}

fun updateLocalTermAgreed(agree: Boolean) {
intent { copy(localTermAgreed = agree) }
}

fun agreeAllTerms(entireTermIds: List<Int>) {
intent { copy(agreedTerms = entireTermIds.toPersistentSet()) }
intent { copy(agreedTerms = entireTermIds.toPersistentSet(), localTermAgreed = true) }
}

fun disagreeAllTerms() {
intent { copy(agreedTerms = persistentSetOf()) }
intent { copy(agreedTerms = persistentSetOf(), localTermAgreed = false) }
}

fun goNextStep() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ fun TermsContent(
descriptionText: String = "",
terms: List<Term> = emptyList(),
agreedTerms: List<Int> = emptyList(),
localTermAgreed: Boolean = false,
onDetailClick: (termId: Int) -> Unit = {},
onSelectAll: (agree: Boolean) -> Unit = {},
onTermChecked: (agree: Boolean, id: Int) -> Unit = { _, _ -> },
onLocalTermChecked: (agree: Boolean) -> Unit = {},
) {
Column(
modifier = modifier.padding(SusuTheme.spacing.spacing_m),
Expand All @@ -48,7 +50,7 @@ fun TermsContent(
Spacer(modifier = Modifier.height(SusuTheme.spacing.spacing_xl))
TermListItem(
title = stringResource(com.susu.feature.loginsignup.R.string.signup_term_agree_all),
checked = agreedTerms.containsAll(terms.map { it.id }),
checked = localTermAgreed && agreedTerms.containsAll(terms.map { it.id }),
isEssential = false,
canRead = false,
onCheckClick = { onSelectAll(it) },
Expand All @@ -57,6 +59,15 @@ fun TermsContent(
thickness = 1.dp,
color = Gray30,
)
TermListItem(
title = stringResource(com.susu.feature.loginsignup.R.string.signup_term_over_14),
checked = localTermAgreed,
isEssential = true,
canRead = false,
onCheckClick = {
onLocalTermChecked(it)
},
)
terms.forEach { term ->
TermListItem(
title = term.title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ 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.android.FileUtils
import com.susu.core.designsystem.theme.SusuTheme
import com.susu.core.ui.INTENT_ACTION_DOWNLOAD_COMPLETE
import com.susu.core.ui.SnackbarToken
Expand Down Expand Up @@ -59,7 +60,13 @@ class MainActivity : ComponentActivity() {
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)))
viewModel.onShowSnackbar(
SnackbarToken(
message = context.getString(com.susu.feature.mypage.R.string.snackbar_success_export),
actionIcon = R.drawable.ic_open,
onClickActionButton = { FileUtils.openFile(context, id) }
)
)
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions feature/navigator/src/main/res/drawable/ic_open.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:pathData="M200,840q-33,0 -56.5,-23.5T120,760v-560q0,-33 23.5,-56.5T200,120h280v80L200,200v560h560v-280h80v280q0,33 -23.5,56.5T760,840L200,840ZM388,628 L332,572 704,200L560,200v-80h280v280h-80v-144L388,628Z"
android:fillColor="#5f6368"/>
</vector>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ data class DateState(
val categoryName: String = "",
val showEndAt: Boolean = true,
val startAt: LocalDateTime? = currentDate,
val endAt: LocalDateTime? = null,
val endAt: LocalDateTime? = currentDate.plusDays(3),
val showStartDateBottomSheet: Boolean = false,
val showEndDateBottomSheet: Boolean = false,
val showOnlyStartAt: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class DateViewModel @Inject constructor(
postSideEffect(DateSideEffect.UpdateParentDate(toUpdateStartAt, toUpdateStartAt))
copy(startAt = toUpdateStartAt)
} else {
postSideEffect(DateSideEffect.UpdateParentDate(toUpdateStartAt, endAt))
copy(startAt = toUpdateStartAt)
postSideEffect(DateSideEffect.UpdateParentDate(toUpdateStartAt, toUpdateStartAt.plusDays(3)))
copy(startAt = toUpdateStartAt, endAt = toUpdateStartAt.plusDays(3))
}
}

Expand All @@ -72,10 +72,10 @@ class DateViewModel @Inject constructor(
endAt = null,
)
} else {
postSideEffect(DateSideEffect.UpdateParentDate(startAt, startAt))
postSideEffect(DateSideEffect.UpdateParentDate(startAt, startAt?.plusDays(3)))
copy(
showOnlyStartAt = true,
endAt = startAt,
endAt = startAt?.plusDays(3),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.susu.core.designsystem.component.appbar.SusuDefaultAppBar
import com.susu.core.designsystem.component.appbar.icon.BackIcon
import com.susu.core.designsystem.component.appbar.icon.DeleteText
import com.susu.core.designsystem.component.badge.BadgeColor
import com.susu.core.designsystem.component.badge.BadgeStyle
import com.susu.core.designsystem.component.badge.SusuBadge
Expand Down Expand Up @@ -112,6 +113,7 @@ fun SentEnvelopeRoute(
onClickBackIcon = viewModel::popBackStack,
onClickEnvelopeDetail = viewModel::navigateSentEnvelopeDetail,
onClickAddEnvelope = viewModel::navigateSentEnvelopeAdd,
onClickDeleteFriend = viewModel::deleteFriend,
)
}

Expand All @@ -125,6 +127,7 @@ fun SentEnvelopeScreen(
onClickBackIcon: () -> Unit = {},
onClickEnvelopeDetail: (Long) -> Unit = {},
onClickAddEnvelope: () -> Unit = {},
onClickDeleteFriend: () -> Unit = {}
) {
val sent = uiState.envelopeInfo.sentAmounts
val received = uiState.envelopeInfo.receivedAmounts
Expand All @@ -139,10 +142,14 @@ fun SentEnvelopeScreen(
) {
Column {
SusuDefaultAppBar(
modifier = Modifier.padding(end = SusuTheme.spacing.spacing_m),
leftIcon = {
BackIcon(onClickBackIcon)
},
title = uiState.envelopeInfo.friend.name,
actions = {
DeleteText(onClickDeleteFriend)
}
)

Column(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope
import com.susu.core.ui.base.BaseViewModel
import com.susu.domain.usecase.envelope.GetEnvelopesHistoryListUseCase
import com.susu.domain.usecase.envelope.GetEnvelopesListUseCase
import com.susu.domain.usecase.friend.DeleteFriendUseCase
import com.susu.feature.sent.navigation.SentRoute
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.toPersistentList
Expand All @@ -15,6 +16,7 @@ import javax.inject.Inject
class SentEnvelopeViewModel @Inject constructor(
private val getEnvelopesListUseCase: GetEnvelopesListUseCase,
private val getEnvelopesHistoryListUseCase: GetEnvelopesHistoryListUseCase,
private val deleteFriendUseCase: DeleteFriendUseCase,
savedStateHandle: SavedStateHandle,
) : BaseViewModel<SentEnvelopeState, SentEnvelopeSideEffect>(
SentEnvelopeState(),
Expand Down Expand Up @@ -58,6 +60,12 @@ class SentEnvelopeViewModel @Inject constructor(
}
}

fun deleteFriend() = viewModelScope.launch {
deleteFriendUseCase(friendId).onSuccess {
postSideEffect(SentEnvelopeSideEffect.PopBackStackWithDeleteFriendId(friendId))
}
}

fun navigateSentEnvelopeAdd() = postSideEffect(SentEnvelopeSideEffect.NavigateEnvelopeAdd(currentState.envelopeInfo.friend))
fun navigateSentEnvelopeDetail(id: Long) = postSideEffect(SentEnvelopeSideEffect.NavigateEnvelopeDetail(id = id))
fun popBackStack() = postSideEffect(SentEnvelopeSideEffect.PopBackStack)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ data class SentState(
val showAlignBottomSheet: Boolean = false,
) : UiState {
val isFiltered = fromAmount != null || toAmount != null || selectedFriendList.isNotEmpty()
val friendIdsForDefend
get() = envelopesList.map { it.friend.id }.toHashSet()
}

data class FriendStatisticsState(
Expand Down
Loading
Loading