diff --git a/add_camera_switch.ps1 b/add_camera_switch.ps1 new file mode 100644 index 0000000..00b63cc --- /dev/null +++ b/add_camera_switch.ps1 @@ -0,0 +1,120 @@ +$path = 'app\src\main\kotlin\com\bodycamera\twentyfoulabs\camera\M530CameraActivity.kt' + +$lines = Get-Content $path +$result = New-Object System.Collections.Generic.List[string] + +$addedVariable = $false +$addedButtonDeclaration = $false +$addedButtonUi = $false +$replacedSelector = $false +$replacedState = $false + +foreach ($line in $lines) { + + # --------------------------------------------------------- + # 1. Variable para saber que camara usa el preview + # --------------------------------------------------------- + if (-not $addedVariable -and + $line -match 'private var lastTouchActionMs = 0L') { + + $result.Add($line) + $result.Add(' private var frontPreviewUsesFrontCamera = true') + $addedVariable = $true + continue + } + + # --------------------------------------------------------- + # 2. Declaracion del boton + # --------------------------------------------------------- + if (-not $addedButtonDeclaration -and + $line -match 'private lateinit var closeButton: Button') { + + $result.Add($line) + $result.Add(' private lateinit var switchCameraButton: Button') + $addedButtonDeclaration = $true + continue + } + + # --------------------------------------------------------- + # 3. Insertar boton antes de captureButton + # --------------------------------------------------------- + if (-not $addedButtonUi -and + $line -match '^\s*captureButton = Button\(this\)\.apply') { + + $result.Add(' switchCameraButton = Button(this).apply {') + $result.Add(' text = "CAMBIAR"') + $result.Add(' setTextColor(Color.WHITE)') + $result.Add(' textSize = 12f') + $result.Add(' setTypeface(typeface, Typeface.BOLD)') + $result.Add(' gravity = Gravity.CENTER') + $result.Add(' minWidth = 0') + $result.Add(' minHeight = 0') + $result.Add(' setPadding(dp(8), 0, dp(8), 0)') + $result.Add(' background = circleDrawable(0xB0000000.toInt(), Color.WHITE, dp(1))') + $result.Add(' visibility = if (mode == MODE_FRONT_PREVIEW) View.VISIBLE else View.GONE') + $result.Add(' elevation = dp(12).toFloat()') + $result.Add('') + $result.Add(' setOnClickListener {') + $result.Add(' if (mode == MODE_FRONT_PREVIEW) {') + $result.Add(' frontPreviewUsesFrontCamera = !frontPreviewUsesFrontCamera') + $result.Add(' startCamera()') + $result.Add(' }') + $result.Add(' }') + $result.Add(' }') + $result.Add('') + $result.Add(' root.addView(') + $result.Add(' switchCameraButton,') + $result.Add(' FrameLayout.LayoutParams(dp(110), dp(48), Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL).apply {') + $result.Add(' bottomMargin = dp(76)') + $result.Add(' }') + $result.Add(' )') + $result.Add('') + + $result.Add($line) + $addedButtonUi = $true + continue + } + + # --------------------------------------------------------- + # 4. Selector dinamico frontal/posterior SOLO para preview + # --------------------------------------------------------- + if (-not $replacedSelector -and + $line -match 'CameraSelector\.DEFAULT_FRONT_CAMERA') { + + $result.Add(' if (frontPreviewUsesFrontCamera)') + $result.Add(' CameraSelector.DEFAULT_FRONT_CAMERA') + $result.Add(' else') + $result.Add(' CameraSelector.DEFAULT_BACK_CAMERA,') + $replacedSelector = $true + continue + } + + # --------------------------------------------------------- + # 5. Cambiar mensaje segun camara + # --------------------------------------------------------- + if (-not $replacedState -and + $line -match 'stateText\.text = "Camara frontal lista"') { + + $result.Add(' stateText.text = if (frontPreviewUsesFrontCamera)') + $result.Add(' "Camara frontal lista"') + $result.Add(' else') + $result.Add(' "Camara posterior lista"') + $replacedState = $true + continue + } + + $result.Add($line) +} + +Set-Content -Path $path -Value $result -Encoding UTF8 + +Write-Host "" +Write-Host "==========================================" +Write-Host "CAMBIO DE CAMARA AGREGADO" +Write-Host "==========================================" +Write-Host "Variable: $addedVariable" +Write-Host "Declaracion boton: $addedButtonDeclaration" +Write-Host "UI boton: $addedButtonUi" +Write-Host "Selector: $replacedSelector" +Write-Host "Estado: $replacedState" +Write-Host "" \ No newline at end of file diff --git a/app/src/main/kotlin/com/bodycamera/twentyfoulabs/MainActivity.kt b/app/src/main/kotlin/com/bodycamera/twentyfoulabs/MainActivity.kt index 66242c8..57753fe 100644 --- a/app/src/main/kotlin/com/bodycamera/twentyfoulabs/MainActivity.kt +++ b/app/src/main/kotlin/com/bodycamera/twentyfoulabs/MainActivity.kt @@ -57,6 +57,7 @@ class MainActivity : ComponentActivity() { @Inject lateinit var authSessionStore: AuthSessionStore @Volatile private var isAuthenticated = false + private var frontPreviewOpened = false companion object { private const val TAG = "MainActivity" @@ -97,7 +98,16 @@ class MainActivity : ComponentActivity() { }) lifecycleScope.launch { - authSessionStore.token.collect { token -> isAuthenticated = !token.isNullOrBlank() } + authSessionStore.token.collect { token -> + isAuthenticated = !token.isNullOrBlank() + + if (isAuthenticated && !frontPreviewOpened) { + frontPreviewOpened = true + runOnUiThread { + openFrontPreview() + } + } + } } registerHardwareReceiver() @@ -222,6 +232,20 @@ class MainActivity : ComponentActivity() { } + + private fun openFrontPreview() { + if (!isAuthenticated) return + + startActivity( + android.content.Intent( + this, + com.bodycamera.twentyfoulabs.camera.M530CameraActivity::class.java + ).putExtra( + com.bodycamera.twentyfoulabs.camera.M530CameraActivity.EXTRA_MODE, + com.bodycamera.twentyfoulabs.camera.M530CameraActivity.MODE_FRONT_PREVIEW + ).addFlags(android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP) + ) + } private fun handlePhotoButton() { startActivity( android.content.Intent( @@ -374,3 +398,4 @@ fun AppNavigation(viewModel: MainViewModel, onOpenPhotoCamera: () -> Unit, onOpe + diff --git a/app/src/main/kotlin/com/bodycamera/twentyfoulabs/camera/M530CameraActivity.kt b/app/src/main/kotlin/com/bodycamera/twentyfoulabs/camera/M530CameraActivity.kt index a0059fa..ed71be7 100644 --- a/app/src/main/kotlin/com/bodycamera/twentyfoulabs/camera/M530CameraActivity.kt +++ b/app/src/main/kotlin/com/bodycamera/twentyfoulabs/camera/M530CameraActivity.kt @@ -1,10 +1,11 @@ -package com.bodycamera.twentyfoulabs.camera +package com.bodycamera.twentyfoulabs.camera import android.Manifest import android.content.ContentValues import android.content.pm.PackageManager import android.graphics.Color import android.graphics.Typeface +import android.graphics.drawable.GradientDrawable import android.os.Build import android.os.Bundle import android.os.SystemClock @@ -54,6 +55,7 @@ class M530CameraActivity : ComponentActivity() { const val EXTRA_MODE = "mode" const val MODE_PHOTO = "photo" const val MODE_VIDEO = "video" + const val MODE_FRONT_PREVIEW = "front_preview" } private lateinit var previewView: PreviewView @@ -63,6 +65,7 @@ class M530CameraActivity : ComponentActivity() { private lateinit var physicalHintText: TextView private lateinit var captureButton: Button private lateinit var closeButton: Button + private lateinit var switchCameraButton: Button private lateinit var recordDot: TextView private lateinit var chronometer: Chronometer @@ -73,10 +76,11 @@ class M530CameraActivity : ComponentActivity() { private var cameraProvider: ProcessCameraProvider? = null private var lastPhysicalActionMs = 0L private var lastTouchActionMs = 0L + private var frontPreviewUsesFrontCamera = true private val cameraPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> - if (granted) startCamera() else stateText.text = "Permiso de cámara requerido" + if (granted) startCamera() else stateText.text = "Permiso de camara requerido" } private val audioPermissionLauncher = @@ -140,7 +144,11 @@ class M530CameraActivity : ComponentActivity() { } modeText = TextView(this).apply { - text = if (mode == MODE_VIDEO) "VIDEO" else "FOTO" + text = when (mode) { + MODE_VIDEO -> "VIDEO" + MODE_FRONT_PREVIEW -> "FRONTAL" + else -> "FOTO" + } setTextColor(if (mode == MODE_VIDEO) 0xFFFF3B30.toInt() else 0xFFFFC400.toInt()) textSize = 14f setTypeface(typeface, Typeface.BOLD) @@ -173,10 +181,11 @@ class M530CameraActivity : ComponentActivity() { setPadding(dp(10), dp(5), dp(10), dp(5)) setBackgroundColor(0x7A000000) isClickable = false + visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE } recordDot = TextView(this).apply { - text = "●" + text = "*" setTextColor(0xFFFF3B30.toInt()) textSize = 18f visibility = View.GONE @@ -203,33 +212,89 @@ class M530CameraActivity : ComponentActivity() { ) closeButton = Button(this).apply { - text = "×" + text = "X" gravity = Gravity.CENTER setTextColor(Color.WHITE) - textSize = 25f + textSize = 18f setTypeface(typeface, Typeface.BOLD) minWidth = 0 minHeight = 0 setPadding(0, 0, 0, 0) - background = circleDrawable(0xB0000000.toInt(), Color.WHITE, dp(1)) + + background = GradientDrawable().apply { + shape = GradientDrawable.OVAL + setColor(0x99000000.toInt()) + setStroke(dp(1), 0xCCFFFFFF.toInt()) + } + isClickable = true isFocusable = true - elevation = dp(12).toFloat() + elevation = dp(8).toFloat() + contentDescription = "Cerrar" + setOnClickListener { stopRecordingIfNeeded() finish() } } + root.addView( closeButton, - FrameLayout.LayoutParams(dp(54), dp(54), Gravity.TOP or Gravity.END).apply { - topMargin = dp(62) + FrameLayout.LayoutParams(dp(44), dp(44), Gravity.TOP or Gravity.END).apply { + topMargin = dp(60) rightMargin = dp(12) } ) + switchCameraButton = Button(this).apply { + text = "CAMARA POSTERIOR" + setTextColor(Color.WHITE) + textSize = 11f + setTypeface(typeface, Typeface.BOLD) + gravity = Gravity.CENTER + minWidth = 0 + minHeight = 0 + setPadding(dp(16), 0, dp(16), 0) + + background = GradientDrawable().apply { + shape = GradientDrawable.RECTANGLE + cornerRadius = dp(24).toFloat() + setColor(0xB31A1A1A.toInt()) + setStroke(dp(1), 0xCCFFFFFF.toInt()) + } + + visibility = if (mode == MODE_FRONT_PREVIEW) View.VISIBLE else View.GONE + elevation = dp(10).toFloat() + contentDescription = "Cambiar camara" + + setOnClickListener { + if (mode == MODE_FRONT_PREVIEW) { + frontPreviewUsesFrontCamera = !frontPreviewUsesFrontCamera + + text = if (frontPreviewUsesFrontCamera) + "CAMARA POSTERIOR" + else + "CAMARA FRONTAL" + + startCamera() + } + } + } + + root.addView( + switchCameraButton, + FrameLayout.LayoutParams( + dp(170), + dp(46), + Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL + ).apply { + bottomMargin = dp(76) + } + ) + captureButton = Button(this).apply { text = if (mode == MODE_VIDEO) "REC" else "FOTO" + visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE setTextColor(Color.WHITE) textSize = 15f setTypeface(typeface, Typeface.BOLD) @@ -289,14 +354,22 @@ class M530CameraActivity : ComponentActivity() { } physicalHintText = TextView(this).apply { - text = if (mode == MODE_VIDEO) "F5 VIDEO" else "F2 FOTO" + text = when (mode) { + MODE_VIDEO -> "F5 VIDEO" + MODE_FRONT_PREVIEW -> "EN VIVO" + else -> "F2 FOTO" + } setTextColor(if (mode == MODE_VIDEO) 0xFFFF3B30.toInt() else 0xFFFFC400.toInt()) textSize = 15f setTypeface(typeface, Typeface.BOLD) } stateText = TextView(this).apply { - text = if (mode == MODE_VIDEO) "Preparando video..." else "Preparando cámara..." + text = when (mode) { + MODE_VIDEO -> "Preparando video..." + MODE_FRONT_PREVIEW -> "Preparando camara frontal..." + else -> "Preparando camara..." + } setTextColor(Color.WHITE) textSize = 13f gravity = Gravity.END or Gravity.CENTER_VERTICAL @@ -335,10 +408,10 @@ class M530CameraActivity : ComponentActivity() { if (now - lastTouchActionMs < 350) return lastTouchActionMs = now - if (mode == MODE_VIDEO) { - toggleVideoRecording() - } else { - takePhoto() + when (mode) { + MODE_VIDEO -> toggleVideoRecording() + MODE_FRONT_PREVIEW -> Unit + else -> takePhoto() } } @@ -355,7 +428,25 @@ class M530CameraActivity : ComponentActivity() { provider.unbindAll() - if (mode == MODE_VIDEO) { + if (mode == MODE_FRONT_PREVIEW) { + imageCapture = null + videoCapture = null + + provider.bindToLifecycle( + this, + if (frontPreviewUsesFrontCamera) + CameraSelector.DEFAULT_FRONT_CAMERA + else + CameraSelector.DEFAULT_BACK_CAMERA, + preview + ) + + stateText.text = if (frontPreviewUsesFrontCamera) + "Camara frontal lista" + else + "Camara posterior lista" + captureButton.isEnabled = false + } else if (mode == MODE_VIDEO) { val recorder = Recorder.Builder() .setQualitySelector( QualitySelector.from( @@ -397,7 +488,7 @@ class M530CameraActivity : ComponentActivity() { captureButton.isEnabled = true } } catch (t: Throwable) { - stateText.text = "Error de cámara" + stateText.text = "Error de camara" captureButton.isEnabled = false } }, ContextCompat.getMainExecutor(this)) @@ -405,7 +496,7 @@ class M530CameraActivity : ComponentActivity() { private fun takePhoto() { val capture = imageCapture ?: run { - stateText.text = "Cámara no lista" + stateText.text = "Camara no lista" return } @@ -624,7 +715,7 @@ class M530CameraActivity : ComponentActivity() { chronometer.visibility = View.GONE recordDot.visibility = View.GONE - stateText.text = if (error) "Error de grabación" else "Video guardado" + stateText.text = if (error) "Error de grabacion" else "Video guardado" physicalHintText.text = "F5 VIDEO" captureButton.text = "REC" @@ -641,6 +732,7 @@ class M530CameraActivity : ComponentActivity() { setBackgroundColor(Color.WHITE) alpha = 0.75f isClickable = false + visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE } val root = findViewById(android.R.id.content) root.addView( @@ -712,3 +804,8 @@ class M530CameraActivity : ComponentActivity() { private fun timestamp(): String = SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.US).format(Date()) } + + + + + diff --git a/apply_front_preview_v2.ps1 b/apply_front_preview_v2.ps1 new file mode 100644 index 0000000..2ee741c --- /dev/null +++ b/apply_front_preview_v2.ps1 @@ -0,0 +1,157 @@ +$cameraPath = 'app\src\main\kotlin\com\bodycamera\twentyfoulabs\camera\M530CameraActivity.kt' +$mainPath = 'app\src\main\kotlin\com\bodycamera\twentyfoulabs\MainActivity.kt' + +$camera = Get-Content $cameraPath -Raw +$main = Get-Content $mainPath -Raw + +# ============================================================ +# M530CameraActivity.kt +# ============================================================ + +# 1. Agregar modo FRONT_PREVIEW +$camera = [regex]::Replace( + $camera, + 'const val MODE_VIDEO = "video"', + 'const val MODE_VIDEO = "video"' + [Environment]::NewLine + + ' const val MODE_FRONT_PREVIEW = "front_preview"', + 1 +) + +# 2. Texto superior +$camera = $camera.Replace( + 'text = if (mode == MODE_VIDEO) "VIDEO" else "FOTO"', + 'text = when (mode) {' + [Environment]::NewLine + + ' MODE_VIDEO -> "VIDEO"' + [Environment]::NewLine + + ' MODE_FRONT_PREVIEW -> "CAMARA FRONTAL"' + [Environment]::NewLine + + ' else -> "FOTO"' + [Environment]::NewLine + + ' }' +) + +# 3. Ocultar botón de captura cuando sea preview frontal +$camera = $camera.Replace( + 'text = if (mode == MODE_VIDEO) "REC" else "FOTO"', + 'text = if (mode == MODE_VIDEO) "REC" else "FOTO"' + [Environment]::NewLine + + ' visibility = if (mode == MODE_FRONT_PREVIEW) View.GONE else View.VISIBLE' +) + +# 4. Texto inferior +$camera = $camera.Replace( + 'text = if (mode == MODE_VIDEO) "F5 VIDEO" else "F2 FOTO"', + 'text = when (mode) {' + [Environment]::NewLine + + ' MODE_VIDEO -> "F5 VIDEO"' + [Environment]::NewLine + + ' MODE_FRONT_PREVIEW -> "VISTA EN VIVO"' + [Environment]::NewLine + + ' else -> "F2 FOTO"' + [Environment]::NewLine + + ' }' +) + +# 5. Estado inicial +$camera = [regex]::Replace( + $camera, + 'text = if \(mode == MODE_VIDEO\) "Preparando video\.\.\." else ".*?"', + 'text = when (mode) {' + [Environment]::NewLine + + ' MODE_VIDEO -> "Preparando video..."' + [Environment]::NewLine + + ' MODE_FRONT_PREVIEW -> "Preparando camara frontal..."' + [Environment]::NewLine + + ' else -> "Preparando camara..."' + [Environment]::NewLine + + ' }', + 1 +) + +# 6. Evitar acciones de foto/video en preview frontal +$camera = [regex]::Replace( + $camera, + 'if \(mode == MODE_VIDEO\) \{\s*toggleVideoRecording\(\)\s*\} else \{\s*takePhoto\(\)\s*\}', + 'when (mode) {' + [Environment]::NewLine + + ' MODE_VIDEO -> toggleVideoRecording()' + [Environment]::NewLine + + ' MODE_FRONT_PREVIEW -> Unit' + [Environment]::NewLine + + ' else -> takePhoto()' + [Environment]::NewLine + + ' }', + 1 +) + +# 7. Usar cámara frontal solo en FRONT_PREVIEW +$camera = [regex]::Replace( + $camera, + '(\s*provider\.unbindAll\(\)\s*)if \(mode == MODE_VIDEO\) \{', + '$1if (mode == MODE_FRONT_PREVIEW) {' + [Environment]::NewLine + + ' imageCapture = null' + [Environment]::NewLine + + ' videoCapture = null' + [Environment]::NewLine + + '' + [Environment]::NewLine + + ' provider.bindToLifecycle(' + [Environment]::NewLine + + ' this,' + [Environment]::NewLine + + ' CameraSelector.DEFAULT_FRONT_CAMERA,' + [Environment]::NewLine + + ' preview' + [Environment]::NewLine + + ' )' + [Environment]::NewLine + + '' + [Environment]::NewLine + + ' stateText.text = "Camara frontal lista"' + [Environment]::NewLine + + ' captureButton.isEnabled = false' + [Environment]::NewLine + + ' } else if (mode == MODE_VIDEO) {', + 1 +) + +# ============================================================ +# MainActivity.kt +# ============================================================ + +# 8. Variable para abrir la cámara frontal una sola vez por inicio +$main = $main.Replace( + '@Volatile private var isAuthenticated = false', + '@Volatile private var isAuthenticated = false' + [Environment]::NewLine + + ' private var frontPreviewOpened = false' +) + +# 9. Al detectar sesión válida, abrir preview frontal +$main = [regex]::Replace( + $main, + 'authSessionStore\.token\.collect \{ token -> isAuthenticated = !token\.isNullOrBlank\(\) \}', + 'authSessionStore.token.collect { token ->' + [Environment]::NewLine + + ' isAuthenticated = !token.isNullOrBlank()' + [Environment]::NewLine + + '' + [Environment]::NewLine + + ' if (isAuthenticated && !frontPreviewOpened) {' + [Environment]::NewLine + + ' frontPreviewOpened = true' + [Environment]::NewLine + + ' runOnUiThread {' + [Environment]::NewLine + + ' openFrontPreview()' + [Environment]::NewLine + + ' }' + [Environment]::NewLine + + ' }' + [Environment]::NewLine + + ' }', + 1 +) + +# 10. Función para abrir la cámara frontal +$frontFunction = @' + + private fun openFrontPreview() { + if (!isAuthenticated) return + + startActivity( + android.content.Intent( + this, + com.bodycamera.twentyfoulabs.camera.M530CameraActivity::class.java + ).putExtra( + com.bodycamera.twentyfoulabs.camera.M530CameraActivity.EXTRA_MODE, + com.bodycamera.twentyfoulabs.camera.M530CameraActivity.MODE_FRONT_PREVIEW + ).addFlags(android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP) + ) + } + +'@ + +$main = $main.Replace( + ' private fun handlePhotoButton() {', + $frontFunction + ' private fun handlePhotoButton() {' +) + +# ============================================================ +# Guardar cambios +# ============================================================ + +Set-Content -Path $cameraPath -Value $camera -Encoding UTF8 +Set-Content -Path $mainPath -Value $main -Encoding UTF8 + +Write-Host '' +Write-Host '==========================================' +Write-Host 'FRONT PREVIEW V2 APLICADO' +Write-Host '==========================================' +Write-Host 'MODE_FRONT_PREVIEW agregado' +Write-Host 'Camara frontal configurada' +Write-Host 'F2 y F5 mantienen camara trasera' +Write-Host '' \ No newline at end of file diff --git a/improve_camera_buttons_ui.ps1 b/improve_camera_buttons_ui.ps1 new file mode 100644 index 0000000..bcf5d60 --- /dev/null +++ b/improve_camera_buttons_ui.ps1 @@ -0,0 +1,174 @@ +$path = 'app\src\main\kotlin\com\bodycamera\twentyfoulabs\camera\M530CameraActivity.kt' + +$c = Get-Content $path -Raw + +# --------------------------------------------------------- +# Import para fondos redondeados +# --------------------------------------------------------- +if ($c -notmatch 'import android\.graphics\.drawable\.GradientDrawable') { + $c = $c.Replace( + 'import android.graphics.Typeface', + "import android.graphics.Typeface`r`nimport android.graphics.drawable.GradientDrawable" + ) +} + +# --------------------------------------------------------- +# Boton CERRAR +# --------------------------------------------------------- +$oldClose = @' + closeButton = Button(this).apply { + text = "X" + gravity = Gravity.CENTER + setTextColor(Color.WHITE) + textSize = 25f + setTypeface(typeface, Typeface.BOLD) + minWidth = 0 + minHeight = 0 + setPadding(0, 0, 0, 0) + background = circleDrawable(0xB0000000.toInt(), Color.WHITE, dp(1)) + isClickable = true + isFocusable = true + elevation = dp(12).toFloat() + setOnClickListener { + stopRecordingIfNeeded() + finish() + } + } + root.addView( + closeButton, + FrameLayout.LayoutParams(dp(54), dp(54), Gravity.TOP or Gravity.END).apply { + topMargin = dp(62) + rightMargin = dp(12) + } + ) +'@ + +$newClose = @' + closeButton = Button(this).apply { + text = "X" + gravity = Gravity.CENTER + setTextColor(Color.WHITE) + textSize = 18f + setTypeface(typeface, Typeface.BOLD) + minWidth = 0 + minHeight = 0 + setPadding(0, 0, 0, 0) + + background = GradientDrawable().apply { + shape = GradientDrawable.OVAL + setColor(0x99000000.toInt()) + setStroke(dp(1), 0xCCFFFFFF.toInt()) + } + + isClickable = true + isFocusable = true + elevation = dp(8).toFloat() + contentDescription = "Cerrar" + + setOnClickListener { + stopRecordingIfNeeded() + finish() + } + } + + root.addView( + closeButton, + FrameLayout.LayoutParams(dp(44), dp(44), Gravity.TOP or Gravity.END).apply { + topMargin = dp(60) + rightMargin = dp(12) + } + ) +'@ + +$c = $c.Replace($oldClose, $newClose) + +# --------------------------------------------------------- +# Boton CAMBIAR CAMARA +# --------------------------------------------------------- +$oldSwitch = @' + switchCameraButton = Button(this).apply { + text = "CAMBIAR" + setTextColor(Color.WHITE) + textSize = 12f + setTypeface(typeface, Typeface.BOLD) + gravity = Gravity.CENTER + minWidth = 0 + minHeight = 0 + setPadding(dp(8), 0, dp(8), 0) + background = circleDrawable(0xB0000000.toInt(), Color.WHITE, dp(1)) + visibility = if (mode == MODE_FRONT_PREVIEW) View.VISIBLE else View.GONE + elevation = dp(12).toFloat() + + setOnClickListener { + if (mode == MODE_FRONT_PREVIEW) { + frontPreviewUsesFrontCamera = !frontPreviewUsesFrontCamera + startCamera() + } + } + } + + root.addView( + switchCameraButton, + FrameLayout.LayoutParams(dp(110), dp(48), Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL).apply { + bottomMargin = dp(76) + } + ) +'@ + +$newSwitch = @' + switchCameraButton = Button(this).apply { + text = "CAMARA POSTERIOR" + setTextColor(Color.WHITE) + textSize = 11f + setTypeface(typeface, Typeface.BOLD) + gravity = Gravity.CENTER + minWidth = 0 + minHeight = 0 + setPadding(dp(16), 0, dp(16), 0) + + background = GradientDrawable().apply { + shape = GradientDrawable.RECTANGLE + cornerRadius = dp(24).toFloat() + setColor(0xB31A1A1A.toInt()) + setStroke(dp(1), 0xCCFFFFFF.toInt()) + } + + visibility = if (mode == MODE_FRONT_PREVIEW) View.VISIBLE else View.GONE + elevation = dp(10).toFloat() + contentDescription = "Cambiar camara" + + setOnClickListener { + if (mode == MODE_FRONT_PREVIEW) { + frontPreviewUsesFrontCamera = !frontPreviewUsesFrontCamera + + text = if (frontPreviewUsesFrontCamera) + "CAMARA POSTERIOR" + else + "CAMARA FRONTAL" + + startCamera() + } + } + } + + root.addView( + switchCameraButton, + FrameLayout.LayoutParams( + dp(170), + dp(46), + Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL + ).apply { + bottomMargin = dp(76) + } + ) +'@ + +$c = $c.Replace($oldSwitch, $newSwitch) + +Set-Content -Path $path -Value $c -Encoding UTF8 + +Write-Host "" +Write-Host "==========================================" +Write-Host "UI DE CAMARA ACTUALIZADA" +Write-Host "==========================================" +Write-Host "" \ No newline at end of file