Skip to content
This repository was archived by the owner on Feb 11, 2025. It is now read-only.

Commit e1e3c36

Browse files
authored
Merge pull request #16 from meganz/release/2.0.4
release/2.0.4
2 parents d1d6456 + 83049a3 commit e1e3c36

27 files changed

Lines changed: 111 additions & 95 deletions

File tree

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
buildscript {
22
ext {
3-
versionCode = 10
4-
versionName = "2.0.3"
3+
versionCode = 11
4+
versionName = "2.0.4"
55
compileSdkVersion = 29
66
minSdkVersion = 21
77
group = "com.github.meganz"

documentscanner/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ dependencies {
6464
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
6565
implementation "androidx.navigation:navigation-fragment-ktx:$navigationVersion"
6666
implementation "androidx.navigation:navigation-ui-ktx:$navigationVersion"
67-
implementation 'androidx.camera:camera-camera2:1.0.0-rc02'
68-
implementation 'androidx.camera:camera-lifecycle:1.0.0-rc02'
69-
implementation 'androidx.camera:camera-view:1.0.0-alpha21'
67+
implementation 'androidx.camera:camera-camera2:1.0.0-rc03'
68+
implementation 'androidx.camera:camera-lifecycle:1.0.0-rc03'
69+
implementation 'androidx.camera:camera-view:1.0.0-alpha22'
7070
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0"
7171
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.0"
7272
kapt "androidx.lifecycle:lifecycle-common-java8:2.3.0"

documentscanner/src/main/java/nz/mega/documentscanner/DocumentScannerActivity.kt

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ class DocumentScannerActivity : AppCompatActivity() {
5252
super.onCreate(savedInstanceState)
5353
initOpenCV()
5454
initFresco()
55-
clearExistingFiles()
5655

5756
binding = ActivityDocumentScannerBinding.inflate(layoutInflater)
5857
setContentView(binding.root)
@@ -79,13 +78,6 @@ class DocumentScannerActivity : AppCompatActivity() {
7978
}
8079
}
8180

82-
private fun clearExistingFiles() {
83-
lifecycleScope.launch {
84-
val result = FileUtils.clearExistingFiles(this@DocumentScannerActivity)
85-
Log.d(TAG, "Cleared existing files: $result")
86-
}
87-
}
88-
8981
private fun setupObservers() {
9082
viewModel.getResultDocument().observe(this, ::onResultDocument)
9183

@@ -119,8 +111,8 @@ class DocumentScannerActivity : AppCompatActivity() {
119111
.setChooserTitle(fileTitle)
120112
.setStream(fileUri)
121113
.createChooserIntent()
114+
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
122115
.apply {
123-
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
124116
putExtra(EXTRA_PICKED_SAVE_DESTINATION, viewModel.getSaveDestination())
125117
}
126118

documentscanner/src/main/java/nz/mega/documentscanner/DocumentScannerViewModel.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@ class DocumentScannerViewModel : ViewModel() {
8383
currentPagePosition.value = position
8484
}
8585

86-
fun setDocumentTitle(title: String) {
87-
if (document.value?.title == title) return
86+
fun setDocumentTitle(title: String?) {
87+
if (title.isNullOrBlank() || document.value?.title == title) return
8888

89-
document.value?.title = title.trim()
89+
document.value?.title = title
9090
document.notifyObserver()
9191
}
9292

documentscanner/src/main/java/nz/mega/documentscanner/camera/CameraFragment.kt

Lines changed: 35 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@ import android.view.LayoutInflater
99
import android.view.View
1010
import android.view.ViewGroup
1111
import android.widget.Toast
12-
import androidx.activity.addCallback
1312
import androidx.camera.core.Camera
1413
import androidx.camera.core.CameraSelector
1514
import androidx.camera.core.ImageAnalysis
1615
import androidx.camera.core.ImageCapture
1716
import androidx.camera.core.ImageCaptureException
1817
import androidx.camera.core.ImageProxy
1918
import androidx.camera.core.Preview
20-
import androidx.camera.core.TorchState
2119
import androidx.camera.lifecycle.ProcessCameraProvider
2220
import androidx.core.content.ContextCompat
2321
import androidx.core.view.isVisible
@@ -31,7 +29,6 @@ import nz.mega.documentscanner.R
3129
import nz.mega.documentscanner.databinding.FragmentCameraBinding
3230
import nz.mega.documentscanner.openCV.ImageScanner
3331
import nz.mega.documentscanner.utils.BitmapUtils.toBitmap
34-
import nz.mega.documentscanner.utils.DialogFactory
3532
import nz.mega.documentscanner.utils.ViewUtils.aspectRatio
3633
import java.util.concurrent.ExecutorService
3734
import java.util.concurrent.Executors
@@ -68,19 +65,18 @@ class CameraFragment : Fragment() {
6865
setupView()
6966
}
7067

71-
override fun onActivityCreated(savedInstanceState: Bundle?) {
72-
super.onActivityCreated(savedInstanceState)
73-
requireActivity().onBackPressedDispatcher.addCallback(this) { showDiscardDialog() }
74-
}
75-
7668
override fun onDestroy() {
7769
cameraExecutor.shutdown()
7870
super.onDestroy()
7971
}
8072

8173
private fun setupView() {
8274
binding.progress.setVisibilityAfterHide(View.GONE)
83-
binding.btnBack.setOnClickListener { showDiscardDialog() }
75+
binding.btnBack.setOnClickListener {
76+
if (!findNavController().popBackStack()) {
77+
activity?.finish()
78+
}
79+
}
8480

8581
if (allPermissionsGranted()) {
8682
binding.cameraView.post { setUpCamera() }
@@ -97,13 +93,15 @@ class CameraFragment : Fragment() {
9793
imageCapture = ImageCapture.Builder()
9894
.setTargetAspectRatio(screenAspectRatio)
9995
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
96+
.setFlashMode(ImageCapture.FLASH_MODE_AUTO)
10097
.build()
10198

102-
imageAnalyzer = ImageAnalysis.Builder()
103-
.setTargetAspectRatio(screenAspectRatio)
104-
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
105-
.build()
106-
.apply { setAnalyzer(cameraExecutor, ::analyzePreviewImage) }
99+
// TODO Disabled until further improvement
100+
// imageAnalyzer = ImageAnalysis.Builder()
101+
// .setTargetAspectRatio(screenAspectRatio)
102+
// .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
103+
// .build()
104+
// .apply { setAnalyzer(cameraExecutor, ::analyzePreviewImage) }
107105

108106
val cameraSelector = CameraSelector.Builder()
109107
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
@@ -119,14 +117,14 @@ class CameraFragment : Fragment() {
119117
viewLifecycleOwner,
120118
cameraSelector,
121119
preview,
122-
imageCapture,
123-
imageAnalyzer
120+
imageCapture
121+
// ,imageAnalyzer
124122
)
125123

126124
preview?.setSurfaceProvider(binding.cameraView.surfaceProvider)
127125

128126
binding.btnCapture.setOnClickListener { takePicture() }
129-
binding.btnTorch.setOnClickListener { toggleTorch() }
127+
binding.btnFlash.setOnClickListener { toggleFlash() }
130128
}, ContextCompat.getMainExecutor(requireContext()))
131129
}
132130

@@ -160,17 +158,28 @@ class CameraFragment : Fragment() {
160158
requestPermissions(arrayOf(Manifest.permission.CAMERA), REQUEST_CODE_PERMISSIONS)
161159
}
162160

163-
private fun toggleTorch() {
164-
camera?.let { camera ->
165-
val newTorchState = camera.cameraInfo.torchState.value != TorchState.ON
166-
val btnIcon = if (newTorchState) {
167-
R.drawable.ic_baseline_flash_on_24
168-
} else {
169-
R.drawable.ic_baseline_flash_off_24
161+
private fun toggleFlash() {
162+
imageCapture?.let { imageCapture ->
163+
val btnIcon: Int
164+
val flashMode: Int
165+
166+
when (imageCapture.flashMode) {
167+
ImageCapture.FLASH_MODE_ON -> {
168+
flashMode = ImageCapture.FLASH_MODE_OFF
169+
btnIcon = R.drawable.ic_baseline_flash_off_24
170+
}
171+
ImageCapture.FLASH_MODE_AUTO -> {
172+
flashMode = ImageCapture.FLASH_MODE_ON
173+
btnIcon = R.drawable.ic_baseline_flash_on_24
174+
}
175+
else -> {
176+
flashMode = ImageCapture.FLASH_MODE_AUTO
177+
btnIcon = R.drawable.ic_baseline_flash_auto_24
178+
}
170179
}
171180

172-
camera.cameraControl.enableTorch(newTorchState)
173-
binding.btnTorch.setImageResource(btnIcon)
181+
imageCapture.flashMode = flashMode
182+
binding.btnFlash.setImageResource(btnIcon)
174183
}
175184
}
176185

@@ -220,24 +229,6 @@ class CameraFragment : Fragment() {
220229
}
221230
}
222231

223-
private fun showDiscardDialog() {
224-
val pagesCount = viewModel.getPagesCount()
225-
226-
when {
227-
pagesCount == 1 -> {
228-
DialogFactory.createDiscardScanDialog(requireContext()) {
229-
viewModel.discardScan()
230-
}.show()
231-
}
232-
pagesCount > 1 -> {
233-
DialogFactory.createDiscardScansDialog(requireContext()) {
234-
viewModel.discardScan()
235-
}.show()
236-
}
237-
else -> viewModel.discardScan()
238-
}
239-
}
240-
241232
private fun showToast(message: String) {
242233
Toast.makeText(requireContext(), message, Toast.LENGTH_LONG).show()
243234
}

documentscanner/src/main/java/nz/mega/documentscanner/save/SaveFragment.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,17 @@ class SaveFragment : Fragment() {
4444

4545
private fun setupView() {
4646
binding.editFileName.doAfterTextChanged { editable ->
47-
editable?.toString()?.let { title ->
48-
viewModel.setDocumentTitle(title)
49-
}
47+
viewModel.setDocumentTitle(editable?.toString())
5048
}
5149

5250
binding.editFileName.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
5351
binding.imgEdit.isVisible = !hasFocus
5452
}
5553

54+
binding.imgEdit.setOnClickListener {
55+
binding.editFileName.requestFocus()
56+
}
57+
5658
binding.chipGroupFileType.setOnCheckedChangeListener { _, checkedId ->
5759
val fileType = when (checkedId) {
5860
R.id.chip_file_type_pdf -> Document.FileType.PDF

documentscanner/src/main/java/nz/mega/documentscanner/scan/ScanFragment.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ class ScanFragment : Fragment() {
6161
binding.viewPager.adapter = adapter
6262
binding.viewPager.setPageTransformer(pageTransformer)
6363
binding.btnBack.setOnClickListener { showDiscardDialog() }
64-
binding.btnAdd.setOnClickListener { navigateBack() }
64+
binding.btnAdd.setOnClickListener {
65+
findNavController().navigate(ScanFragmentDirections.actionScanFragmentToCameraFragment())
66+
}
6567
binding.btnRotate.setOnClickListener { viewModel.rotatePage(requireContext()) }
6668
binding.btnDelete.setOnClickListener {
6769
DialogFactory.createDeleteCurrentScanDialog(requireContext()) {
@@ -72,7 +74,7 @@ class ScanFragment : Fragment() {
7274
binding.btnDone.setOnClickListener { findNavController().navigate(ScanFragmentDirections.actionScanFragmentToSaveFragment()) }
7375
binding.btnRetake.setOnClickListener {
7476
viewModel.retakePage()
75-
navigateBack()
77+
findNavController().navigate(ScanFragmentDirections.actionScanFragmentToCameraFragment())
7678
}
7779
}
7880

documentscanner/src/main/java/nz/mega/documentscanner/scan/ScanPagerAdapter.kt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ package nz.mega.documentscanner.scan
22

33
import android.view.LayoutInflater
44
import android.view.ViewGroup
5-
import androidx.recyclerview.widget.ListAdapter
5+
import androidx.recyclerview.widget.RecyclerView
66
import nz.mega.documentscanner.data.Page
77
import nz.mega.documentscanner.databinding.ItemScanBinding
88

9-
class ScanPagerAdapter : ListAdapter<Page, ScanPagerViewHolder>(Page.ItemDiffUtil()) {
9+
class ScanPagerAdapter : RecyclerView.Adapter<ScanPagerViewHolder>() {
10+
11+
private var items = emptyList<Page>()
1012

1113
init {
1214
setHasStableIds(true)
@@ -19,9 +21,17 @@ class ScanPagerAdapter : ListAdapter<Page, ScanPagerViewHolder>(Page.ItemDiffUti
1921
}
2022

2123
override fun onBindViewHolder(holder: ScanPagerViewHolder, position: Int) {
22-
holder.bind(getItem(position))
24+
holder.bind(items[position])
2325
}
2426

27+
override fun getItemCount(): Int =
28+
items.size
29+
2530
override fun getItemId(position: Int): Long =
26-
getItem(position).id
31+
items[position].id
32+
33+
fun submitList(items: List<Page>) {
34+
this.items = items
35+
notifyDataSetChanged()
36+
}
2737
}

documentscanner/src/main/java/nz/mega/documentscanner/utils/DialogFactory.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,24 @@ import nz.mega.documentscanner.R
99
object DialogFactory {
1010

1111
fun createDiscardScanDialog(context: Context, callback: () -> Unit): MaterialAlertDialogBuilder =
12-
createDialog(context, callback, R.string.scan_dialog_discard_title, R.string.scan_dialog_discard_body)
12+
createDialog(context, callback, R.string.scan_dialog_discard_title, R.string.scan_dialog_discard_body, R.string.scan_dialog_discard_action)
1313

1414
fun createDiscardScansDialog(context: Context, callback: () -> Unit): MaterialAlertDialogBuilder =
15-
createDialog(context, callback, R.string.scan_dialog_discard_all_title, R.string.scan_dialog_discard_all_body)
15+
createDialog(context, callback, R.string.scan_dialog_discard_all_title, R.string.scan_dialog_discard_all_body, R.string.scan_dialog_discard_action)
1616

1717
fun createDeleteCurrentScanDialog(context: Context, callback: () -> Unit): MaterialAlertDialogBuilder =
18-
createDialog(context, callback, R.string.scan_dialog_delete_body, null)
18+
createDialog(context, callback, R.string.scan_dialog_delete_body)
1919

2020
private fun createDialog(
2121
context: Context,
2222
callback: () -> Unit,
2323
@StringRes titleRes: Int,
24-
@StringRes bodyRes: Int?
24+
@StringRes bodyRes: Int? = null,
25+
@StringRes actionRes: Int? = null
2526
): MaterialAlertDialogBuilder =
2627
MaterialAlertDialogBuilder(context)
2728
.setTitle(titleRes)
2829
.setNegativeButton(android.R.string.cancel, null)
29-
.setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int -> callback.invoke() }
30+
.setPositiveButton(actionRes ?: android.R.string.ok) { _: DialogInterface, _: Int -> callback.invoke() }
3031
.apply { bodyRes?.let { setMessage(it) } }
3132
}

documentscanner/src/main/java/nz/mega/documentscanner/utils/FileUtils.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ import java.io.FileOutputStream
1111
@Suppress("BlockingMethodInNonBlockingContext")
1212
object FileUtils {
1313

14-
const val FILE_NAME_FORMAT = "Scanned_%1tY%<tm%<td%<tH%<tM"
14+
const val FILE_NAME_FORMAT = "Scanned_%1tY%<tm%<td%<tH%<tM%<tS"
1515

1616
private const val ROOT_FILE_DIR = "scans"
1717
private const val PAGE_FILE_DIR = "$ROOT_FILE_DIR/pages/"
1818
private const val DOCUMENT_FILE_DIR = "$ROOT_FILE_DIR/document/"
1919

2020
private suspend fun getParentFile(context: Context, parentDir: String): File =
2121
withContext(Dispatchers.IO) {
22-
File(context.filesDir, parentDir).apply {
22+
File(context.cacheDir, parentDir).apply {
2323
if (!exists()) {
2424
mkdirs()
2525
}

0 commit comments

Comments
 (0)