Skip to content

Commit

Permalink
Merge pull request #51 from Team-BuddyCon/feat/barcode
Browse files Browse the repository at this point in the history
바코드 인식 API 사용하여 이미지 등록
  • Loading branch information
ows3090 authored Feb 25, 2024
2 parents c400942 + 641493a commit 9834206
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,33 @@ package com.yapp.buddycon.designsystem.component.dialog
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.yapp.buddycon.designsystem.R
import com.yapp.buddycon.designsystem.theme.BuddyConTheme

@Composable
fun ConfirmDialog(
dialogTitle: String,
dialogContent: String? = null,
onClick: (() -> Unit)? = null
onClick: (() -> Unit)? = null,
onDismissRequest: () -> Unit = {}
) {
BaseDialog(
dialogTitle = dialogTitle,
dialogContent = dialogContent,
dialogButtons = listOf(
DialogButtons.Light(
title = stringResource(id = R.string.confirm),
action = onClick
Dialog(
properties = DialogProperties(usePlatformDefaultWidth = false),
onDismissRequest = onDismissRequest
) {
BaseDialog(
dialogTitle = dialogTitle,
dialogContent = dialogContent,
dialogButtons = listOf(
DialogButtons.Light(
title = stringResource(id = R.string.confirm),
action = onClick
)
)
)
)
}
}

@Preview
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.yapp.buddycon.designsystem.component.dialog

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.yapp.buddycon.designsystem.theme.BuddyConTheme

@Composable
Expand All @@ -10,23 +12,28 @@ fun DefaultDialog(
dismissText: String,
confirmText: String,
dialogContent: String? = null,
onDismiss: (() -> Unit)? = null,
onConfirm: (() -> Unit)? = null
onConfirm: (() -> Unit)? = null,
onDismissRequest: (() -> Unit) = {}
) {
BaseDialog(
dialogTitle = dialogTitle,
dialogContent = dialogContent,
dialogButtons = listOf(
DialogButtons.Dark(
title = dismissText,
action = onDismiss
),
DialogButtons.Light(
title = confirmText,
action = onConfirm
Dialog(
properties = DialogProperties(usePlatformDefaultWidth = false),
onDismissRequest = onDismissRequest
) {
BaseDialog(
dialogTitle = dialogTitle,
dialogContent = dialogContent,
dialogButtons = listOf(
DialogButtons.Dark(
title = dismissText,
action = onDismissRequest
),
DialogButtons.Light(
title = confirmText,
action = onConfirm
)
)
)
)
}
}

@Preview
Expand Down
3 changes: 3 additions & 0 deletions core/designsystem/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,7 @@
<string name="map">지도</string>
<string name="map_location_permission">위치 정보를 허용했어요!</string>

<!-- Error Popup-->
<string name="gifticon_register_error">쿠폰을 등록하지 못했어요</string>
<string name="gifticon_register_error_reason">바코드가 잘리거나 손상되지 않았는지\n확인 후에 다시 시도해 주세요.</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.yapp.buddycon.navigation.gifticon

import androidx.compose.runtime.remember
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
Expand All @@ -22,10 +24,12 @@ fun NavGraphBuilder.gifticonGraph(
}
}

composable(GifticonDestination.Register.route) {
GifticonRegisterScreen {
navHostController.popBackStack()
}
composable(GifticonDestination.Register.route) { entry ->
val parentEntry = remember(entry) { navHostController.getBackStackEntry(GifticonDestination.Gifticon.route) }
GifticonRegisterScreen(
gifticonViewModel = hiltViewModel(parentEntry),
onBack = { navHostController.popBackStack() }
)
}
}
}
3 changes: 3 additions & 0 deletions feature/gifticon/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ dependencies {
implementation libs.androidx.activity.compose
implementation platform(libs.androidx.compose.bom)
implementation libs.bundles.androidx.compose
implementation libs.barcode.scanning
implementation libs.timber

testImplementation libs.junit
androidTestImplementation libs.androidx.junit
androidTestImplementation libs.androidx.espresso.core
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,33 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material3.FabPosition
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.yapp.buddycon.designsystem.R
import com.yapp.buddycon.designsystem.component.appbar.TopAppBarWithNotification
import com.yapp.buddycon.designsystem.component.button.FloatingActionButton
import com.yapp.buddycon.designsystem.component.dialog.ConfirmDialog
import com.yapp.buddycon.designsystem.theme.BuddyConTheme
import com.yapp.buddycon.gifticon.available.AvailabeGifticonScreen

@Composable
fun GifticonScreeen(
gifticonViewModel: GifticonViewModel = hiltViewModel(),
onNavigateToRegister: () -> Unit = {}
) {
val showErrorPopup by gifticonViewModel.showErrorPopup.collectAsStateWithLifecycle()
if (showErrorPopup) {
ConfirmDialog(
dialogTitle = stringResource(R.string.gifticon_register_error),
dialogContent = stringResource(R.string.gifticon_register_error_reason),
onClick = { gifticonViewModel.showGifticonRegisterError(false) },
onDismissRequest = { gifticonViewModel.showGifticonRegisterError(false) }
)
}

Scaffold(
topBar = {
TopAppBarWithNotification(stringResource(R.string.gifticon))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.yapp.buddycon.gifticon

import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import javax.inject.Inject

@HiltViewModel
class GifticonViewModel @Inject constructor() : ViewModel() {

private val _showErrorPopup = MutableStateFlow(false)
val showErrorPopup = _showErrorPopup.asStateFlow()

fun showGifticonRegisterError(isShow: Boolean) {
_showErrorPopup.value = isShow
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import androidx.compose.ui.window.DialogProperties
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil.compose.AsyncImage
import com.google.mlkit.vision.barcode.BarcodeScanning
import com.google.mlkit.vision.common.InputImage
import com.yapp.buddycon.designsystem.R
import com.yapp.buddycon.designsystem.component.appbar.TopAppBarWithBack
import com.yapp.buddycon.designsystem.component.button.BuddyConButton
Expand All @@ -58,17 +60,42 @@ import com.yapp.buddycon.designsystem.theme.BuddyConTheme
import com.yapp.buddycon.designsystem.theme.Grey30
import com.yapp.buddycon.designsystem.theme.Grey70
import com.yapp.buddycon.designsystem.theme.Paddings
import com.yapp.buddycon.gifticon.GifticonViewModel
import timber.log.Timber
import java.io.IOException

@Composable
fun GifticonRegisterScreen(
gifticonViewModel: GifticonViewModel = hiltViewModel(),
onBack: () -> Unit = {}
) {
val context = LocalContext.current
val coroutineScope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }
var imageUri by remember { mutableStateOf<Uri?>(null) }
val galleryLauncher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri ->
imageUri = uri
try {
val image = uri?.let { InputImage.fromFilePath(context, it) }
val scanner = BarcodeScanning.getClient()
image?.let { image ->
scanner.process(image)
.addOnSuccessListener { barcodes ->
if (barcodes.isNotEmpty()) {
imageUri = uri
} else {
Timber.d("There is not barcode in image")
gifticonViewModel.showGifticonRegisterError(true)
onBack()
}
}.addOnFailureListener {
Timber.e("barcode scanner detection error: ${it.message}")
gifticonViewModel.showGifticonRegisterError(true)
onBack()
}
}
} catch (e: IOException) {
e.printStackTrace()
}
}

LaunchedEffect(imageUri) {
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ timber = "5.0.1"

## 3rd library
coil-compose = "2.4.0"
barcode-scanning = "17.2.0"

## retrofit2
retrofit2 = "2.9.0"
Expand Down Expand Up @@ -85,6 +86,7 @@ accompanist-pager-indicators = { group = "com.google.accompanist", name = "accom

## 3rd library
coil-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil-compose" }
barcode-scanning = { group = "com.google.mlkit", name = "barcode-scanning", version.ref = "barcode-scanning" }

## retrofit2
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit2" }
Expand Down

0 comments on commit 9834206

Please sign in to comment.