Skip to content

Commit

Permalink
Merge pull request #340 from Nexters/feature/Boolti-337
Browse files Browse the repository at this point in the history
Feature/boolti 337 공연 등록 툴바 추가 등
  • Loading branch information
mangbaam authored Nov 18, 2024
2 parents 09fa66b + 86daacf commit bb85f08
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 18 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<activity
android:name=".presentation.screen.MainActivity"
android:exported="true"
android:windowSoftInputMode="adjustResize"
android:theme="@style/Theme.Boolti">

<intent-filter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import android.webkit.ValueCallback
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow

class BtWebView @JvmOverloads constructor(
context: Context,
Expand All @@ -16,7 +18,13 @@ class BtWebView @JvmOverloads constructor(
defStyleRes: Int = 0,
) : WebView(context, attrs, defStyleAttr, defStyleRes) {

private val _progress = MutableStateFlow(0)
val progress = _progress.asStateFlow()

init {
isFocusable = true
isFocusableInTouchMode = true

setupSettings()
setupWebViewClient()
}
Expand All @@ -39,7 +47,11 @@ class BtWebView @JvmOverloads constructor(
launchActivity: () -> Unit,
setFilePathCallback: (ValueCallback<Array<Uri>>) -> Unit,
) {
webChromeClient = BtWebChromeClient(launchActivity, setFilePathCallback)
webChromeClient = BtWebChromeClient(
launchActivity = launchActivity,
setFilePathCallback = setFilePathCallback,
onProgressChanged = { _progress.value = it },
)
}
}

Expand All @@ -48,7 +60,13 @@ class BtWebViewClient : WebViewClient()
class BtWebChromeClient(
private val launchActivity: () -> Unit,
private val setFilePathCallback: (ValueCallback<Array<Uri>>) -> Unit,
private val onProgressChanged: (Int) -> Unit = {},
) : WebChromeClient() {
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
onProgressChanged(newProgress)
}

override fun onShowFileChooser(
webView: WebView,
filePathCallback: ValueCallback<Array<Uri>>?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ import com.nexters.boolti.presentation.screen.reservations.ReservationsScreen
import com.nexters.boolti.presentation.screen.showdetail.ShowDetailContentScreen
import com.nexters.boolti.presentation.screen.showdetail.ShowDetailScreen
import com.nexters.boolti.presentation.screen.showdetail.ShowImagesScreen
import com.nexters.boolti.presentation.screen.showregistration.addShowRegistration
import com.nexters.boolti.presentation.screen.signout.SignoutScreen
import com.nexters.boolti.presentation.screen.ticket.detail.TicketDetailScreen
import com.nexters.boolti.presentation.screen.ticketing.TicketingScreen
import com.nexters.boolti.presentation.screen.showregistration.addShowRegistration
import com.nexters.boolti.presentation.theme.BooltiTheme
import com.nexters.boolti.presentation.util.SnackbarController
import com.nexters.boolti.presentation.util.rememberNavControllerWithLog
Expand Down Expand Up @@ -254,7 +254,10 @@ fun MainNavigation(modifier: Modifier, onClickQrScan: (showId: String, showName:
)
}

addShowRegistration()
addShowRegistration(
modifier = modifier,
popBackStack = navController::popBackStack,
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import com.nexters.boolti.presentation.screen.MainDestination

fun NavGraphBuilder.addShowRegistration(
modifier: Modifier = Modifier,
popBackStack: () -> Unit,
) {
composable(
route = MainDestination.ShowRegistration.route,
) {
ShowRegistrationScreen(
modifier = modifier,
onClickBack = popBackStack,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,54 @@ package com.nexters.boolti.presentation.screen.showregistration

import android.annotation.SuppressLint
import android.net.Uri
import android.view.ViewGroup
import android.webkit.CookieManager
import android.webkit.ValueCallback
import android.webkit.WebStorage
import android.webkit.WebView
import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.viewinterop.AndroidView
import androidx.hilt.navigation.compose.hiltViewModel
import com.nexters.boolti.presentation.BuildConfig
import com.nexters.boolti.presentation.R
import com.nexters.boolti.presentation.component.BTDialog
import com.nexters.boolti.presentation.component.BtBackAppBar
import com.nexters.boolti.presentation.component.BtCircularProgressIndicator
import com.nexters.boolti.presentation.component.BtWebView
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.launch
import timber.log.Timber

@OptIn(ExperimentalLayoutApi::class)
@SuppressLint("SetJavaScriptEnabled")
@Composable
fun ShowRegistrationScreen(
modifier: Modifier = Modifier,
onClickBack: () -> Unit,
viewModel: ShowRegistrationViewModel = hiltViewModel(),
) {
var filePathCallback: ValueCallback<Array<Uri>>? by remember { mutableStateOf(null) }
Expand All @@ -38,6 +61,13 @@ fun ShowRegistrationScreen(
val domain = BuildConfig.DOMAIN
val url = "https://${domain}/show/add"

var showExitDialog by mutableStateOf(false)

val scope = rememberCoroutineScope()
var webView: WebView? by remember { mutableStateOf(null) }
var webviewProgress by remember { mutableIntStateOf(0) }
val loading by remember { derivedStateOf { webviewProgress < 100 } }

LaunchedEffect(Unit) {
CookieManager.getInstance().removeAllCookies(null)
WebStorage.getInstance().deleteAllData()
Expand All @@ -54,22 +84,68 @@ fun ShowRegistrationScreen(
}
}

AndroidView(
BackHandler {
if (webView?.canGoBack() == true) webView?.goBack() else showExitDialog = true
}

Scaffold(
modifier = modifier,
factory = { context ->
BtWebView(context).apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
)
setWebChromeClient(
launchActivity = { launcher.launch(arrayOf("image/*")) },
setFilePathCallback = { callback -> filePathCallback = callback },
)
loadUrl(url)
topBar = {
BtBackAppBar(
title = stringResource(R.string.my_register_show),
onClickBack = { showExitDialog = true },
)
},
) { innerPadding ->
Box(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
.imePadding(),
) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
BtWebView(context).apply {
setWebChromeClient(
launchActivity = { launcher.launch(arrayOf("image/*")) },
setFilePathCallback = { callback -> filePathCallback = callback },
)
Timber.d("내가 만든 쿠키 : ${CookieManager.getInstance().getCookie(url)}")

scope.launch {
progress.collect { webviewProgress = it }
}
}.also { webView = it }
},
update = { webView -> webView.loadUrl(url) },
)

Timber.d("내가 만든 쿠키 : ${CookieManager.getInstance().getCookie(url)}")
AnimatedVisibility(
visible = loading,
modifier = Modifier.align(Alignment.Center),
exit = fadeOut(),
) {
BtCircularProgressIndicator()
}

if (showExitDialog) {
BTDialog(
positiveButtonLabel = stringResource(R.string.btn_exit),
onClickPositiveButton = {
showExitDialog = false
onClickBack()
},
onClickNegativeButton = { showExitDialog = false },
onDismiss = { showExitDialog = false },
) {
Text(
text = stringResource(R.string.exit_register_msg),
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
}
}
)
}
}
1 change: 1 addition & 0 deletions presentation/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@
<string name="my_scan_qr">입장 확인</string>
<string name="my_logout_popup">정말 로그아웃 하시겠어요?</string>
<string name="my_register_show">공연 등록</string>
<string name="exit_register_msg">공연 등록을 종료하시겠어요?</string>
<string name="show_profile_button">프로필 보기</string>
<string name="account_setting">계정 설정</string>
<string name="my_show">내 공연</string>
Expand Down

0 comments on commit bb85f08

Please sign in to comment.