From c7c466b7f73320b8601dfcde4b058a644ddbc77b Mon Sep 17 00:00:00 2001
From: Rifqi222 <mrifki193@gmail.com>
Date: Thu, 28 Mar 2024 21:31:20 +0700
Subject: [PATCH] add: add scan init

---
 .../java/com/pbd/psi/ui/scan/ScanFragment.kt  | 186 ++++++++++++++----
 .../java/com/pbd/psi/ui/scan/ScanViewModel.kt |  13 ++
 app/src/main/res/drawable/scan_button.png     | Bin 0 -> 10675 bytes
 .../main/res/layout-land/fragment_twibbon.xml |   4 +-
 app/src/main/res/layout/activity_scan.xml     |  27 +++
 app/src/main/res/layout/dialog_scan.xml       |  41 ++++
 app/src/main/res/layout/fragment_scan.xml     |  21 +-
 app/src/main/res/layout/fragment_twibbon.xml  |   4 +-
 8 files changed, 249 insertions(+), 47 deletions(-)
 create mode 100644 app/src/main/java/com/pbd/psi/ui/scan/ScanViewModel.kt
 create mode 100644 app/src/main/res/drawable/scan_button.png
 create mode 100644 app/src/main/res/layout/activity_scan.xml
 create mode 100644 app/src/main/res/layout/dialog_scan.xml

diff --git a/app/src/main/java/com/pbd/psi/ui/scan/ScanFragment.kt b/app/src/main/java/com/pbd/psi/ui/scan/ScanFragment.kt
index f5166de..f34f6ec 100644
--- a/app/src/main/java/com/pbd/psi/ui/scan/ScanFragment.kt
+++ b/app/src/main/java/com/pbd/psi/ui/scan/ScanFragment.kt
@@ -1,60 +1,162 @@
 package com.pbd.psi.ui.scan
 
+import android.Manifest
+import android.app.Activity
+import android.app.AlertDialog
+import android.content.Intent
+import android.graphics.BitmapFactory
+import android.graphics.drawable.BitmapDrawable
+import android.net.Uri
 import android.os.Bundle
-import androidx.fragment.app.Fragment
+import android.os.Handler
+import android.os.Looper
+import android.provider.MediaStore
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import com.pbd.psi.R
-
-// TODO: Rename parameter arguments, choose names that match
-// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
-private const val ARG_PARAM1 = "param1"
-private const val ARG_PARAM2 = "param2"
-
-/**
- * A simple [Fragment] subclass.
- * Use the [ScanFragment.newInstance] factory method to
- * create an instance of this fragment.
- */
+import android.widget.Toast
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.camera.core.CameraSelector
+import androidx.camera.core.ImageCapture
+import androidx.camera.core.Preview
+import androidx.camera.lifecycle.ProcessCameraProvider
+import androidx.core.content.ContextCompat
+import androidx.fragment.app.Fragment
+import com.pbd.psi.databinding.FragmentScanBinding
+
 class ScanFragment : Fragment() {
-    // TODO: Rename and change types of parameters
-    private var param1: String? = null
-    private var param2: String? = null
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        arguments?.let {
-            param1 = it.getString(ARG_PARAM1)
-            param2 = it.getString(ARG_PARAM2)
+
+    private var _binding: FragmentScanBinding? = null
+    private val binding get() = _binding!!
+
+    private var imageCapture: ImageCapture? = null
+
+    private var previewFrozen: Boolean = false
+    private var cameraProvider: ProcessCameraProvider? = null
+
+    private val filePickerLauncher = registerForActivityResult(
+        ActivityResultContracts.StartActivityForResult()
+    ) { result ->
+        if (result.resultCode == Activity.RESULT_OK) {
+            val selectedImageUri = result.data?.data
+            selectedImageUri?.let { uri ->
+                loadSelectedImage(uri)
+            }
         }
     }
 
     override fun onCreateView(
-        inflater: LayoutInflater, container: ViewGroup?,
+        inflater: LayoutInflater,
+        container: ViewGroup?,
         savedInstanceState: Bundle?
-    ): View? {
-        // Inflate the layout for this fragment
-        return inflater.inflate(R.layout.fragment_scan, container, false)
+    ): View {
+        _binding = FragmentScanBinding.inflate(inflater, container, false)
+        val root: View = binding.root
+
+        val permissionLauncher = registerForActivityResult(
+            ActivityResultContracts.RequestPermission()
+        ) { isGranted ->
+            if (isGranted) {
+                startCamera()
+            }
+        }
+
+        permissionLauncher.launch(Manifest.permission.CAMERA)
+
+        imageCapture = ImageCapture.Builder().build()
+
+        binding.scanButton?.setOnClickListener {
+            previewMask()
+        }
+
+        binding.uploadImage?.setOnClickListener{
+            openFileExplorer()
+        }
+
+        return root
+    }
+
+    private fun startCamera() {
+        val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
+        cameraProviderFuture.addListener({
+
+            cameraProvider = cameraProviderFuture.get()
+
+            val preview = Preview.Builder().build().also {
+                    mPreview ->
+                if (!previewFrozen) {
+                    mPreview.setSurfaceProvider(binding.scanView?.surfaceProvider)
+                } else {
+                    mPreview.setSurfaceProvider(null)
+                }
+            }
+
+            imageCapture = ImageCapture.Builder().build()
+
+            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
+
+            try {
+                cameraProvider?.unbindAll()
+                cameraProvider?.bindToLifecycle(this, cameraSelector, preview!!)
+            } catch (e: Exception) {
+                Log.d("CameraX", "startCamera Failed:", e)
+            }
+        }, ContextCompat.getMainExecutor(requireContext()))
+    }
+
+    private fun previewMask() {
+        binding.scanButton?.isEnabled = false
+        previewFrozen = !previewFrozen
+        startCamera()
+
+        Handler(Looper.getMainLooper()).postDelayed({
+            // TO DO: Add  modal
+            val builder: AlertDialog.Builder = AlertDialog.Builder(context)
+            builder
+                .setMessage("Do you want to retake the picture?")
+                .setPositiveButton("Yes") { dialog, which ->
+                    dialog.dismiss()
+                    binding.scanButton?.isEnabled = true
+                    previewFrozen = !previewFrozen
+                    startCamera()
+                }
+                .setNegativeButton("No") { dialog, which ->
+                    // TO DO : send a froze preview to the server as img form data
+                    dialog.dismiss()
+                }
+
+            val dialog: AlertDialog = builder.create()
+            dialog.show()
+        }, 1000)
+    }
+
+    private fun openFileExplorer() {
+        val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
+        filePickerLauncher.launch(intent)
     }
 
-    companion object {
-        /**
-         * Use this factory method to create a new instance of
-         * this fragment using the provided parameters.
-         *
-         * @param param1 Parameter 1.
-         * @param param2 Parameter 2.
-         * @return A new instance of fragment ScanFragment.
-         */
-        // TODO: Rename and change types and number of parameters
-        @JvmStatic
-        fun newInstance(param1: String, param2: String) =
-            ScanFragment().apply {
-                arguments = Bundle().apply {
-                    putString(ARG_PARAM1, param1)
-                    putString(ARG_PARAM2, param2)
+    private fun loadSelectedImage(uri: Uri) {
+        try {
+            requireContext().contentResolver.openInputStream(uri)?.use { inputStream ->
+                val bitmap = BitmapFactory.decodeStream(inputStream)
+                if (bitmap != null) {
+                    val drawable = BitmapDrawable(resources, bitmap)
+                    binding.scanView?.background = drawable
+                } else {
+                    Toast.makeText(requireContext(), "Failed to decode image", Toast.LENGTH_SHORT).show()
+                    Log.e("ScanFragment", "Failed to decode image")
                 }
             }
+        } catch (e: Exception) {
+            Toast.makeText(requireContext(), "Failed to load image", Toast.LENGTH_SHORT).show()
+            Log.e("ScanFragment", "Failed to load image", e)
+        }
+    }
+
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        _binding = null
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/pbd/psi/ui/scan/ScanViewModel.kt b/app/src/main/java/com/pbd/psi/ui/scan/ScanViewModel.kt
new file mode 100644
index 0000000..3fb5128
--- /dev/null
+++ b/app/src/main/java/com/pbd/psi/ui/scan/ScanViewModel.kt
@@ -0,0 +1,13 @@
+package com.pbd.psi.ui.twibbon
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+
+class ScanViewModel : ViewModel() {
+
+    private val _text = MutableLiveData<String>().apply {
+        value = "This is Scan Fragment"
+    }
+    val text: LiveData<String> = _text
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/scan_button.png b/app/src/main/res/drawable/scan_button.png
new file mode 100644
index 0000000000000000000000000000000000000000..f3a65e62f1681264fc21b5a5ac2a2bfce2b3548d
GIT binary patch
literal 10675
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

literal 0
HcmV?d00001

diff --git a/app/src/main/res/layout-land/fragment_twibbon.xml b/app/src/main/res/layout-land/fragment_twibbon.xml
index c00eeb4..4e4ec75 100644
--- a/app/src/main/res/layout-land/fragment_twibbon.xml
+++ b/app/src/main/res/layout-land/fragment_twibbon.xml
@@ -64,7 +64,7 @@
         android:background="@drawable/capture_button"
         android:layout_marginTop="10dp"
         android:layout_marginLeft="40dp"
-        android:layout_width="142dip"
+        android:layout_width="159dip"
         android:layout_height="52dip"
         android:contentDescription="@string/capture"
         app:layout_constraintEnd_toStartOf="@id/changeButton"
@@ -78,7 +78,7 @@
         android:background="@drawable/change_button"
         android:layout_marginTop="10dp"
         android:layout_marginRight="40dp"
-        android:layout_width="142dip"
+        android:layout_width="159dip"
         android:layout_height="52dip"
         android:contentDescription="@string/change"
         app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/activity_scan.xml b/app/src/main/res/layout/activity_scan.xml
new file mode 100644
index 0000000..40df589
--- /dev/null
+++ b/app/src/main/res/layout/activity_scan.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/payment"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingTop="0dp"
+    tools:context=".ScanActivity">
+
+    <FrameLayout
+        android:id="@+id/placeholderPayment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginStart="0dp"
+        android:layout_marginEnd="0dp"
+        android:background="?android:attr/windowBackground"
+        app:itemBackground="@color/primaryDarkest"
+        app:itemIconTint="@color/white"
+        app:itemTextColor="@color/white"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent">
+    </FrameLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_scan.xml b/app/src/main/res/layout/dialog_scan.xml
new file mode 100644
index 0000000..30de4c2
--- /dev/null
+++ b/app/src/main/res/layout/dialog_scan.xml
@@ -0,0 +1,41 @@
+<!-- res/layout/dialog_retake_image.xml -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:padding="16dp"
+    android:id="@+id/dialog_scan">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Do you want to retake the image?"
+        android:textSize="18sp"
+        android:textColor="@android:color/black"
+        android:layout_gravity="center_horizontal"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginTop="16dp">
+
+        <Button
+            android:id="@+id/btnRetake"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="Retake"
+            android:textColor="@android:color/white"
+            android:background="@color/primaryDarkest"/>
+
+        <Button
+            android:id="@+id/btnUse"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text="Use"
+            android:textColor="@android:color/white"
+            android:background="@color/primaryDarkest"/>
+    </LinearLayout>
+</LinearLayout>
diff --git a/app/src/main/res/layout/fragment_scan.xml b/app/src/main/res/layout/fragment_scan.xml
index bab875d..4c64d8b 100644
--- a/app/src/main/res/layout/fragment_scan.xml
+++ b/app/src/main/res/layout/fragment_scan.xml
@@ -52,6 +52,19 @@
         android:layout_width="50dip"
         android:layout_height="50dip"
         android:contentDescription="@string/upload_image"
+        app:layout_constraintStart_toEndOf="@id/scan_button"
+        app:layout_constraintTop_toBottomOf="@+id/guideline"/>
+
+    <ImageButton
+        android:id="@+id/scan_button"
+        android:layout_marginVertical="20dp"
+        android:layout_marginStart="10dp"
+        android:fontFamily="@font/montserrat"
+        android:gravity="center_horizontal"
+        android:background="@drawable/scan_button"
+        android:layout_width="50dip"
+        android:layout_height="50dip"
+        android:contentDescription="@string/upload_image"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@+id/guideline"/>
 
@@ -78,7 +91,13 @@
         app:layout_constraintBottom_toTopOf="@+id/guideline"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toBottomOf="@+id/scan_header" />
+        app:layout_constraintTop_toBottomOf="@+id/scan_header">
+
+        <androidx.camera.view.PreviewView
+            android:id="@+id/scan_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"/>
+    </FrameLayout>
 
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_twibbon.xml b/app/src/main/res/layout/fragment_twibbon.xml
index 975295f..3adadb3 100644
--- a/app/src/main/res/layout/fragment_twibbon.xml
+++ b/app/src/main/res/layout/fragment_twibbon.xml
@@ -66,7 +66,7 @@
         android:gravity="center_horizontal"
         android:background="@drawable/capture_button"
         android:layout_marginTop="10dp"
-        android:layout_width="142dip"
+        android:layout_width="159dip"
         android:layout_height="52dip"
         android:contentDescription="@string/capture"
         app:layout_constraintEnd_toStartOf="@id/changeButton"
@@ -79,7 +79,7 @@
         android:gravity="center_horizontal"
         android:background="@drawable/change_button"
         android:layout_marginTop="10dp"
-        android:layout_width="142dip"
+        android:layout_width="159dip"
         android:layout_height="52dip"
         android:contentDescription="@string/change"
         app:layout_constraintEnd_toEndOf="parent"
-- 
GitLab