diff --git a/data/src/main/java/com/nexters/boolti/data/network/response/HostedShowDto.kt b/data/src/main/java/com/nexters/boolti/data/network/response/HostedShowDto.kt
index 29708fe86..7ed2383f3 100644
--- a/data/src/main/java/com/nexters/boolti/data/network/response/HostedShowDto.kt
+++ b/data/src/main/java/com/nexters/boolti/data/network/response/HostedShowDto.kt
@@ -1,5 +1,7 @@
package com.nexters.boolti.data.network.response
+import com.nexters.boolti.data.util.toLocalDate
+import com.nexters.boolti.data.util.toLocalDateTime
import com.nexters.boolti.domain.model.Show
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@@ -10,13 +12,16 @@ import java.time.LocalDateTime
internal data class HostedShowDto(
@SerialName("showId") val showId: String,
@SerialName("showName") val showName: String,
+ @SerialName("date") val date: String,
+ @SerialName("salesStartTime") val salesStartDate: String,
+ @SerialName("salesEndTime") val salesEndDate: String,
) {
fun toDomain(): Show = Show(
id = showId,
name = showName,
- date = LocalDateTime.now(),
- salesStartDate = LocalDate.now(),
- salesEndDate = LocalDate.now(),
+ date = date.toLocalDateTime(),
+ salesStartDate = salesStartDate.toLocalDate(),
+ salesEndDate = salesEndDate.toLocalDate(),
thumbnailImage = "",
)
}
diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml
index ad4f4ba0d..a7cb6c9ab 100644
--- a/presentation/src/main/AndroidManifest.xml
+++ b/presentation/src/main/AndroidManifest.xml
@@ -2,5 +2,6 @@
+
\ No newline at end of file
diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/QrScanActivity.kt b/presentation/src/main/java/com/nexters/boolti/presentation/QrScanActivity.kt
index 404bd2ed6..74e0fe15d 100644
--- a/presentation/src/main/java/com/nexters/boolti/presentation/QrScanActivity.kt
+++ b/presentation/src/main/java/com/nexters/boolti/presentation/QrScanActivity.kt
@@ -2,7 +2,9 @@ package com.nexters.boolti.presentation
import android.Manifest
import android.graphics.Color
+import android.hardware.Camera
import android.os.Bundle
+import android.os.VibrationEffect
import android.view.KeyEvent
import androidx.activity.ComponentActivity
import androidx.activity.SystemBarStyle
@@ -19,6 +21,7 @@ import com.journeyapps.barcodescanner.BarcodeResult
import com.journeyapps.barcodescanner.DecoratedBarcodeView
import com.journeyapps.barcodescanner.DefaultDecoderFactory
import com.nexters.boolti.presentation.extension.requestPermission
+import com.nexters.boolti.presentation.extension.vibrator
import com.nexters.boolti.presentation.screen.qr.QrScanScreen
import com.nexters.boolti.presentation.theme.BooltiTheme
import dagger.hilt.android.AndroidEntryPoint
@@ -27,6 +30,7 @@ import kotlinx.coroutines.launch
@AndroidEntryPoint
class QrScanActivity : ComponentActivity() {
+ private var isBackCamera = true
private val barcodeView: DecoratedBarcodeView by lazy {
DecoratedBarcodeView(this).apply {
@@ -43,6 +47,14 @@ class QrScanActivity : ComponentActivity() {
private val callback = BarcodeCallback { result: BarcodeResult ->
result.text ?: return@BarcodeCallback
viewModel.scan(result.text)
+
+ vibrator.vibrate(
+ VibrationEffect.createOneShot(
+ 100,
+ VibrationEffect.DEFAULT_AMPLITUDE
+ )
+ )
+
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
barcodeView.pause()
@@ -63,7 +75,8 @@ class QrScanActivity : ComponentActivity() {
BooltiTheme {
QrScanScreen(
barcodeView = barcodeView,
- onClickClose = { finish() }
+ onClickClose = { finish() },
+ onClickSwitchCamera = ::switchCamera
)
}
}
@@ -82,4 +95,15 @@ class QrScanActivity : ComponentActivity() {
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
return barcodeView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event)
}
+
+ private fun switchCamera() {
+ barcodeView.pause()
+ isBackCamera = !isBackCamera
+ barcodeView.cameraSettings.requestedCameraId = if (isBackCamera) {
+ Camera.CameraInfo.CAMERA_FACING_BACK
+ } else {
+ Camera.CameraInfo.CAMERA_FACING_FRONT
+ }
+ barcodeView.resume()
+ }
}
diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/component/CircleBgIcon.kt b/presentation/src/main/java/com/nexters/boolti/presentation/component/CircleBgIcon.kt
index 3c68a133f..5e5959e0f 100644
--- a/presentation/src/main/java/com/nexters/boolti/presentation/component/CircleBgIcon.kt
+++ b/presentation/src/main/java/com/nexters/boolti/presentation/component/CircleBgIcon.kt
@@ -9,11 +9,12 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.graphics.vector.ImageVector
@Composable
fun CircleBgIcon(
modifier: Modifier = Modifier,
- painter: Painter,
+ imageVector: ImageVector,
bgColor: Color,
) {
Box(
@@ -21,6 +22,6 @@ fun CircleBgIcon(
.clip(CircleShape)
.background(bgColor)
) {
- Icon(painter = painter, contentDescription = null)
+ Icon(imageVector = imageVector, contentDescription = null)
}
}
diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/component/ToastSnackbarHost.kt b/presentation/src/main/java/com/nexters/boolti/presentation/component/ToastSnackbarHost.kt
index f5b0e0138..b6cb025a6 100644
--- a/presentation/src/main/java/com/nexters/boolti/presentation/component/ToastSnackbarHost.kt
+++ b/presentation/src/main/java/com/nexters/boolti/presentation/component/ToastSnackbarHost.kt
@@ -38,7 +38,7 @@ fun ToastSnackbarHost(
) {
if (leadingIcon != null) {
leadingIcon()
- Spacer(modifier = Modifier.padding(end = 12.dp))
+ Spacer(modifier = Modifier.padding(end = 8.dp))
}
Text(
modifier = Modifier.padding(vertical = 12.dp),
diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/extension/Context.kt b/presentation/src/main/java/com/nexters/boolti/presentation/extension/Context.kt
index 6a71a2ead..ccab08655 100644
--- a/presentation/src/main/java/com/nexters/boolti/presentation/extension/Context.kt
+++ b/presentation/src/main/java/com/nexters/boolti/presentation/extension/Context.kt
@@ -4,7 +4,12 @@ import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.content.pm.PackageManager
+import android.os.Build
+import android.os.VibrationEffect
+import android.os.Vibrator
+import android.os.VibratorManager
import androidx.core.content.ContextCompat
+import androidx.core.content.ContextCompat.getSystemService
fun Context.requireActivity(): Activity {
var ctx = this
@@ -24,3 +29,10 @@ fun Context.requireActivity(): Activity {
fun Context.checkGrantedPermission(permission: String): Boolean {
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
}
+
+val Context.vibrator: Vibrator
+ get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ (getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager).defaultVibrator
+ } else {
+ getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
+ }
\ No newline at end of file
diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/screen/qr/HostedShowScreen.kt b/presentation/src/main/java/com/nexters/boolti/presentation/screen/qr/HostedShowScreen.kt
index 7000af1fe..37665aa0c 100644
--- a/presentation/src/main/java/com/nexters/boolti/presentation/screen/qr/HostedShowScreen.kt
+++ b/presentation/src/main/java/com/nexters/boolti/presentation/screen/qr/HostedShowScreen.kt
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
@@ -36,7 +37,7 @@ import com.nexters.boolti.presentation.R
import com.nexters.boolti.presentation.component.BtBackAppBar
import com.nexters.boolti.presentation.theme.BooltiTheme
import com.nexters.boolti.presentation.theme.Grey30
-import com.nexters.boolti.presentation.theme.Grey60
+import com.nexters.boolti.presentation.theme.Grey50
import com.nexters.boolti.presentation.theme.point1
import java.time.LocalDate
import java.time.LocalDateTime
@@ -60,7 +61,9 @@ fun HostedShowScreen(
}
) { innerPadding ->
if (uiState.shows.isEmpty()) {
- EmptyHostedShow(modifier = modifier.padding(innerPadding))
+ EmptyHostedShow(modifier = modifier
+ .padding(innerPadding)
+ .fillMaxSize())
} else {
HostedShows(
modifier = modifier
@@ -96,7 +99,7 @@ private fun HostedShowItem(
onClick: (showId: String, showName: String) -> Unit,
) {
val enable = LocalDate.now().toEpochDay() <= show.date.toLocalDate().toEpochDay()
- val tint = if (enable) White else Grey60
+ val tint = if (enable) White else Grey50
Row(
modifier = Modifier
@@ -119,18 +122,6 @@ private fun HostedShowItem(
}
}
-@Preview
-@Composable
-fun HostedShowItemPreview() {
- BooltiTheme {
- Surface {
- HostedShowItem(
- Show("", "hello world", LocalDateTime.now(), LocalDate.now(), LocalDate.now(), "")
- ) { _, _ -> }
- }
- }
-}
-
@Composable
fun EmptyHostedShow(
modifier: Modifier,
@@ -163,3 +154,46 @@ fun EmptyHostedShow(
}
}
}
+
+@Preview
+@Composable
+fun HostedShowItemPreview() {
+ BooltiTheme {
+ Surface {
+ HostedShowItem(
+ Show("", "hello world", LocalDateTime.now(), LocalDate.now(), LocalDate.now(), "")
+ ) { _, _ -> }
+ }
+ }
+}
+
+@Preview
+@Composable
+fun OutDatedHostedShowItemPreview() {
+ BooltiTheme {
+ Surface {
+ HostedShowItem(
+ Show(
+ "",
+ "hello world",
+ LocalDateTime.now().minusDays(1),
+ LocalDate.now(),
+ LocalDate.now(),
+ ""
+ )
+ ) { _, _ -> }
+ }
+ }
+}
+
+@Preview(widthDp = 360, heightDp = 760)
+@Composable
+fun EmptyShowItemPreview() {
+ BooltiTheme {
+ Surface {
+ EmptyHostedShow(
+ Modifier
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/screen/qr/QrScanScreen.kt b/presentation/src/main/java/com/nexters/boolti/presentation/screen/qr/QrScanScreen.kt
index 966433862..d1faec25f 100644
--- a/presentation/src/main/java/com/nexters/boolti/presentation/screen/qr/QrScanScreen.kt
+++ b/presentation/src/main/java/com/nexters/boolti/presentation/screen/qr/QrScanScreen.kt
@@ -1,13 +1,19 @@
package com.nexters.boolti.presentation.screen.qr
+import android.content.Context
+import android.hardware.camera2.CameraCharacteristics
+import android.hardware.camera2.CameraManager
import androidx.compose.foundation.background
+import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBarsPadding
+import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -21,14 +27,19 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.hilt.navigation.compose.hiltViewModel
@@ -39,13 +50,17 @@ import com.nexters.boolti.presentation.QrScanEvent
import com.nexters.boolti.presentation.QrScanViewModel
import com.nexters.boolti.presentation.R
import com.nexters.boolti.presentation.component.BTDialog
-import com.nexters.boolti.presentation.component.BtCloseableAppBar
+import com.nexters.boolti.presentation.component.BtAppBar
+import com.nexters.boolti.presentation.component.BtAppBarDefaults
import com.nexters.boolti.presentation.component.CircleBgIcon
import com.nexters.boolti.presentation.component.ToastSnackbarHost
import com.nexters.boolti.presentation.theme.Error
+import com.nexters.boolti.presentation.theme.Grey30
import com.nexters.boolti.presentation.theme.Grey50
import com.nexters.boolti.presentation.theme.Success
import com.nexters.boolti.presentation.theme.Warning
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
@@ -53,11 +68,11 @@ fun QrScanScreen(
barcodeView: DecoratedBarcodeView,
viewModel: QrScanViewModel = hiltViewModel(),
onClickClose: () -> Unit,
+ onClickSwitchCamera: () -> Unit,
) {
var showEntryCodeDialog by remember { mutableStateOf(false) }
val snackbarHostState = remember { SnackbarHostState() }
var snackbarIconId by remember { mutableStateOf(null) }
- val scope = rememberCoroutineScope()
val successMessage = stringResource(R.string.message_ticket_validated)
val notTodayErrMessage = stringResource(R.string.error_show_not_today)
@@ -65,76 +80,130 @@ fun QrScanScreen(
val notMatchedErrMessage = stringResource(R.string.error_ticket_not_matched)
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+ var bottomPadding by remember { mutableStateOf(0.dp) }
+ var borderColor: Color by remember { mutableStateOf(Color.Transparent) }
+ var showingBorderJob: Job? = null
+
+ val context = LocalContext.current
+ val cameraSwitchable = rememberSaveable { hasBothSidesCameras(context) }
LaunchedEffect(barcodeView) {
barcodeView.resume()
}
LaunchedEffect(viewModel.event) {
- scope.launch {
- viewModel.event.collect { event ->
- val (iconId, errMessage) = when (event) {
- is QrScanEvent.ScanError -> {
- when (event.errorType) {
- QrErrorType.ShowNotToday -> Pair(
- R.drawable.ic_warning,
- notTodayErrMessage
- )
+ viewModel.event.collect { event ->
+ val (iconId, errMessage, color) = when (event) {
+ is QrScanEvent.ScanError -> {
+ when (event.errorType) {
+ QrErrorType.ShowNotToday -> Triple(
+ R.drawable.ic_warning,
+ notTodayErrMessage,
+ Warning
+ )
- QrErrorType.UsedTicket -> Pair(
- R.drawable.ic_error,
- usedTicketErrMessage
- )
+ QrErrorType.UsedTicket -> Triple(
+ R.drawable.ic_error,
+ usedTicketErrMessage,
+ Error
+ )
- QrErrorType.TicketNotFound -> Pair(
- R.drawable.ic_error,
- notMatchedErrMessage
- )
- }
+ QrErrorType.TicketNotFound -> Triple(
+ R.drawable.ic_error,
+ notMatchedErrMessage,
+ Error
+ )
}
-
- is QrScanEvent.ScanSuccess -> Pair(R.drawable.ic_error, successMessage)
}
- snackbarIconId = iconId
+
+ is QrScanEvent.ScanSuccess -> Triple(
+ R.drawable.ic_error,
+ successMessage,
+ Success
+ )
+ }
+ snackbarIconId = iconId
+
+ launch {
+ snackbarHostState.currentSnackbarData?.dismiss()
snackbarHostState.showSnackbar(errMessage)
}
+
+ showingBorderJob?.cancel()
+ showingBorderJob = launch {
+ borderColor = color
+ delay(4000L)
+ borderColor = Color.Transparent
+ }
}
}
Scaffold(
modifier = Modifier.navigationBarsPadding(),
topBar = {
- BtCloseableAppBar(
+ BtAppBar(
title = uiState.showName,
- onClickClose = onClickClose,
+ navigateButtons = {
+ BtAppBarDefaults.AppBarIconButton(
+ onClick = onClickClose,
+ iconRes = R.drawable.ic_arrow_back,
+ )
+ },
+ actionButtons = {
+ if (cameraSwitchable) {
+ BtAppBarDefaults.AppBarIconButton(
+ onClick = onClickSwitchCamera,
+ iconRes = R.drawable.ic_camera_flip,
+ )
+ }
+ }
)
},
bottomBar = {
QrScanBottombar { showEntryCodeDialog = true }
},
snackbarHost = {
- ToastSnackbarHost(
- hostState = snackbarHostState,
- modifier = Modifier.padding(bottom = 100.dp),
- leadingIcon = {
- snackbarIconId?.let {
- CircleBgIcon(
- painter = painterResource(it),
- bgColor = when (it) {
- R.drawable.ic_check -> Success
- R.drawable.ic_error -> Error
- else -> Warning
- }
- )
- }
- },
- )
+ Box(
+ modifier = Modifier.fillMaxSize(),
+ contentAlignment = Alignment.TopCenter,
+ ) {
+ ToastSnackbarHost(
+ modifier = Modifier
+ .offset { // Scaffold의 inner padding 만큼 상단을 뚫고 나가는 문제가 있음. 해당 값 보정.
+ IntOffset(
+ 0,
+ bottomPadding
+ .toPx()
+ .toInt()
+ )
+ }
+ .padding(top = 18.dp + 44.dp), // 44.dp 는 top bar 높이 값 수동 계산
+ hostState = snackbarHostState,
+ leadingIcon = {
+ snackbarIconId?.let {
+ CircleBgIcon(
+ imageVector = ImageVector.vectorResource(it),
+ bgColor = when (it) {
+ R.drawable.ic_check -> Success
+ R.drawable.ic_error -> Error
+ else -> Warning
+ }
+ )
+ }
+ },
+ )
+ }
},
) { innerPadding ->
+ LaunchedEffect(innerPadding) {
+ bottomPadding = innerPadding.calculateBottomPadding()
+ }
+
AndroidView(
modifier = Modifier
.padding(innerPadding)
- .fillMaxSize(),
+ .fillMaxSize()
+ .border(width = 2.dp, color = borderColor),
factory = { barcodeView },
)
@@ -149,12 +218,20 @@ fun QrScanScreen(
@Composable
private fun QrScanBottombar(onClick: () -> Unit) {
- Box(
+ Column(
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.background),
- contentAlignment = Alignment.Center,
+ horizontalAlignment = Alignment.CenterHorizontally,
) {
+ Text(
+ modifier = Modifier.padding(top = 20.dp),
+ text = stringResource(R.string.entry_code_notice),
+ textAlign = TextAlign.Center,
+ style = MaterialTheme.typography.bodySmall.copy(
+ color = Grey50,
+ ),
+ )
Row(
modifier = Modifier
.clickable(onClick = onClick)
@@ -167,13 +244,13 @@ private fun QrScanBottombar(onClick: () -> Unit) {
.size(20.dp)
.padding(end = 4.dp),
painter = painterResource(id = R.drawable.ic_book),
- tint = Grey50,
+ tint = Grey30,
contentDescription = stringResource(R.string.show_entry_code),
)
Text(
text = stringResource(id = R.string.show_entry_code),
- style = MaterialTheme.typography.bodySmall,
- color = Grey50,
+ style = MaterialTheme.typography.titleSmall,
+ color = Grey30,
)
}
}
@@ -202,3 +279,26 @@ private fun EntryCodeDialog(
)
}
}
+
+private fun hasBothSidesCameras(context: Context): Boolean {
+ val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
+ val cameraIds = cameraManager.cameraIdList
+
+ var hasFrontCamera = false
+ var hasBackCamera = false
+
+ for (cameraId in cameraIds) {
+ val characteristics = cameraManager.getCameraCharacteristics(cameraId)
+ val lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING)
+
+ if (lensFacing == CameraCharacteristics.LENS_FACING_FRONT) {
+ hasFrontCamera = true
+ }
+
+ if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
+ hasBackCamera = true
+ }
+ }
+
+ return hasFrontCamera && hasBackCamera
+}
\ No newline at end of file
diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/theme/Theme.kt b/presentation/src/main/java/com/nexters/boolti/presentation/theme/Theme.kt
index 66b58cffe..699b26ac3 100644
--- a/presentation/src/main/java/com/nexters/boolti/presentation/theme/Theme.kt
+++ b/presentation/src/main/java/com/nexters/boolti/presentation/theme/Theme.kt
@@ -1,9 +1,15 @@
package com.nexters.boolti.presentation.theme
+import android.app.Activity
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
+import androidx.compose.ui.graphics.toArgb
+import androidx.compose.ui.platform.LocalView
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowCompat
private val DarkColorScheme = darkColorScheme(
primary = Orange01,
@@ -19,39 +25,22 @@ private val DarkColorScheme = darkColorScheme(
onSurfaceVariant = Grey15,
outline = Grey80,
outlineVariant = Grey10,
-
-// secondary = PurpleGrey80,
-// tertiary = Pink80
-)
-
-private val LightColorScheme = lightColorScheme(
-// primary = Purple40,
-// secondary = PurpleGrey40,
-// tertiary = Pink40
-
- /* Other default colors to override
- background = Color(0xFFFFFBFE),
- surface = Color(0xFFFFFBFE),
- onPrimary = Color.White,
- onSecondary = Color.White,
- onTertiary = Color.White,
- onBackground = Color(0xFF1C1B1F),
- onSurface = Color(0xFF1C1B1F),
- */
)
@Composable
fun BooltiTheme(
- darkTheme: Boolean = true, // FIXME light theme이 추가된다면 이 부분을 isSystemInDarkTheme()로 수정하세요.
content: @Composable () -> Unit
) {
- val colorScheme = when {
- darkTheme -> DarkColorScheme
- else -> LightColorScheme
+ val view = LocalView.current
+ if (!view.isInEditMode) {
+ SideEffect {
+ val window = (view.context as Activity).window
+ WindowCompat.getInsetsController(window, view).isAppearanceLightNavigationBars = false
+ }
}
MaterialTheme(
- colorScheme = colorScheme,
+ colorScheme = DarkColorScheme,
typography = Typography,
content = content
)
diff --git a/presentation/src/main/res/drawable/ic_camera_flip.xml b/presentation/src/main/res/drawable/ic_camera_flip.xml
new file mode 100644
index 000000000..63fbd7efc
--- /dev/null
+++ b/presentation/src/main/res/drawable/ic_camera_flip.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml
index 17bdc172a..ca164b633 100644
--- a/presentation/src/main/res/values/strings.xml
+++ b/presentation/src/main/res/values/strings.xml
@@ -18,7 +18,7 @@
모두 지우기
아직 공연일이 아니에요
- 이미 사용된 티켓이에요
+ 이미 입장에 사용한 티켓이에요
이 공연의 티켓이 아니에요
존재하지 않는 티켓이에요
@@ -241,7 +241,8 @@
입장 코드는 주최자 계정의 마이 > QR 스캔 > 해당 공연 스캐너에서 확인 가능해요.
입장 코드를 입력해 주세요
올바른 입장 코드를 입력해 주세요
- 입장코드 보기
+ 입장 코드 보기
+ QR 코드가 인식되지 않을 경우 티켓 화면 하단의\n\'입장 코드 입력하기\'에 아래 입장 코드를 입력해 주세요.
코드 복사
식별 코드를 복사했어요
@@ -322,11 +323,11 @@
링크를 삭제했어요
유효한 링크가 아니에요
-
- QR 스캔
- 주최한 공연이 없어요
- 공연을 주최하고 QR 스캐너로\n관객 입장을 관리해 보세요
- 사용되었어요
+
+ 입장 확인
+ 입장을 확인할 공연이 없어요
+ 공연을 주최하고 QR 코드로\n관객 입장을 확인해 보세요
+ 입장을 확인했어요
결제 내역이 없어요