Skip to content

Commit

Permalink
Merge pull request #1585 from minvws/5664
Browse files Browse the repository at this point in the history
5664
  • Loading branch information
ktiniatros authored Jun 20, 2023
2 parents 5cace57 + df22990 commit 8123b35
Show file tree
Hide file tree
Showing 16 changed files with 370 additions and 222 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ sealed class DialogButtonData(open val textId: Int) : Parcelable {
@Parcelize
data class Dismiss(override val textId: Int) :
DialogButtonData(textId), Parcelable

@Parcelize
data class NavigateUp(override val textId: Int) :
DialogButtonData(textId), Parcelable
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.os.Bundle
import android.os.Parcelable
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.navigation.fragment.findNavController
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.parcelize.Parcelize
import nl.rijksoverheid.ctr.design.R
Expand Down Expand Up @@ -70,6 +71,10 @@ class SharedDialogFragment : DialogFragment() {
is DialogButtonData.Dismiss -> {
dialog.dismiss()
}

is DialogButtonData.NavigateUp -> {
findNavController().navigateUp()
}
}
dialog.dismiss()
}
Expand Down
2 changes: 1 addition & 1 deletion holder/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def appVersionCode = 1000000
if (System.getenv("GITHUB_REPOSITORY_OWNER") == "minvws") {
appVersionCode = System.getenv("VERSION_NUMBER") != null ? System.getenv("VERSION_NUMBER").toInteger() : 1000000
}
version = "4.13"
version = "5.0"
archivesBaseName = "holder-v${version}-${appVersionCode}"

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import nl.rijksoverheid.ctr.holder.paper_proof.usecases.ValidatePaperProofDomest
import nl.rijksoverheid.ctr.holder.paper_proof.usecases.ValidatePaperProofDomesticInputCodeUseCaseImpl
import nl.rijksoverheid.ctr.holder.paper_proof.usecases.ValidatePaperProofDomesticUseCase
import nl.rijksoverheid.ctr.holder.paper_proof.usecases.ValidatePaperProofDomesticUseCaseImpl
import nl.rijksoverheid.ctr.holder.pdf.PreviewPdfUseCase
import nl.rijksoverheid.ctr.holder.pdf.PreviewPdfUseCaseImpl
import nl.rijksoverheid.ctr.holder.pdf.PrintExportDccUseCase
import nl.rijksoverheid.ctr.holder.pdf.PrintExportDccUseCaseImpl
import nl.rijksoverheid.ctr.holder.qrcodes.usecases.QrCodeUseCase
Expand Down Expand Up @@ -98,4 +100,5 @@ val eventsUseCasesModule = module {
factory<DataMigrationImportUseCase> { DataMigrationImportUseCaseImpl(get(), get()) }
factory<DataMigrationPayloadUseCase> { DataMigrationPayloadUseCaseImpl(get(), get()) }
factory<PrintExportDccUseCase> { PrintExportDccUseCaseImpl(get(), get(), get()) }
factory<PreviewPdfUseCase> { PreviewPdfUseCaseImpl() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import nl.rijksoverheid.ctr.holder.paper_proof.PaperProofDomesticInputCodeViewMo
import nl.rijksoverheid.ctr.holder.paper_proof.PaperProofDomesticInputCodeViewModelImpl
import nl.rijksoverheid.ctr.holder.paper_proof.PaperProofQrScannerViewModel
import nl.rijksoverheid.ctr.holder.paper_proof.PaperProofQrScannerViewModelImpl
import nl.rijksoverheid.ctr.holder.pdf.PdfPreviewViewModel
import nl.rijksoverheid.ctr.holder.pdf.PdfPreviewViewModelImpl
import nl.rijksoverheid.ctr.holder.pdf.PdfWebViewModel
import nl.rijksoverheid.ctr.holder.pdf.PdfWebViewModelImpl
import nl.rijksoverheid.ctr.holder.qrcodes.QrCodesViewModel
Expand Down Expand Up @@ -74,4 +76,5 @@ val viewModels = module {
viewModel<DataMigrationShowQrCodeViewModel> { DataMigrationShowQrCodeViewModelImpl(get(), get()) }
viewModel<DataMigrationScanQrViewModel> { DataMigrationScanQrViewModelImpl(get(), get(), get()) }
viewModel<PdfWebViewModel> { PdfWebViewModelImpl(androidContext().filesDir.path, get(), get()) }
viewModel<PdfPreviewViewModel> { PdfPreviewViewModelImpl(get()) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright (c) 2023 De Staat der Nederlanden, Ministerie van Volksgezondheid, Welzijn en Sport.
* Licensed under the EUROPEAN UNION PUBLIC LICENCE v. 1.2
*
* SPDX-License-Identifier: EUPL-1.2
*
*/
package nl.rijksoverheid.ctr.holder.pdf

data class PDfPreviewInfo(val content: String, val initialZoom: Int)
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ class PdfExportedFragment : Fragment(R.layout.fragment_pdf_exported) {
val binding = FragmentPdfExportedBinding.bind(view)

binding.previewPdfButton.setOnClickListener {
navigateSafety(PdfExportedFragmentDirections.actionPdfPreview())
navigateSafety(
PdfExportedFragmentDirections.actionPdfPreview(
toolbarTitle = PdfWebViewFragment.pdfFileName
)
)
}

binding.savePdfButton.setOnClickListener {
Expand Down
13 changes: 13 additions & 0 deletions holder/src/main/java/nl/rijksoverheid/ctr/holder/pdf/PdfPreview.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright (c) 2023 De Staat der Nederlanden, Ministerie van Volksgezondheid, Welzijn en Sport.
* Licensed under the EUROPEAN UNION PUBLIC LICENCE v. 1.2
*
* SPDX-License-Identifier: EUPL-1.2
*
*/
package nl.rijksoverheid.ctr.holder.pdf

sealed class PdfPreview {
class Success(val info: PDfPreviewInfo) : PdfPreview()
object Error : PdfPreview()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,60 @@
*/
package nl.rijksoverheid.ctr.holder.pdf

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.pdf.PdfRenderer
import android.os.Bundle
import android.os.ParcelFileDescriptor
import android.view.View
import androidx.fragment.app.Fragment
import java.io.File
import nl.rijksoverheid.ctr.design.utils.DialogButtonData
import nl.rijksoverheid.ctr.design.utils.DialogFragmentData
import nl.rijksoverheid.ctr.holder.R
import nl.rijksoverheid.ctr.holder.databinding.FragmentPdfPreviewBinding
import nl.rijksoverheid.ctr.shared.ext.findNavControllerSafety
import nl.rijksoverheid.ctr.shared.ext.navigateSafety
import nl.rijksoverheid.ctr.shared.livedata.EventObserver
import org.koin.androidx.viewmodel.ext.android.viewModel

class PdfPreviewFragment : Fragment(R.layout.fragment_pdf_preview) {

private val viewModel: PdfPreviewViewModel by viewModel()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val binding = FragmentPdfPreviewBinding.bind(view)

try {
val pdfFile = File(requireContext().filesDir, PdfWebViewFragment.pdfFileName)
val parcelFileDescriptor =
ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY)
val pdfRenderer = PdfRenderer(parcelFileDescriptor)
val bitmaps = mutableListOf<Bitmap>()
for (i in 0 until pdfRenderer.pageCount) {
val currentPage = pdfRenderer.openPage(i)
val bitmap = Bitmap.createBitmap(
currentPage.width,
currentPage.height,
Bitmap.Config.ARGB_8888
)
currentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
bitmaps.add(bitmap)
currentPage.close()
}
pdfRenderer.close()
binding.pdfImageView.setImageBitmap(pdfBitmap(bitmaps))
} catch (exception: Exception) {
findNavControllerSafety()?.popBackStack()
}
}
binding.pdfWebView.settings.builtInZoomControls = true
binding.pdfWebView.settings.displayZoomControls = false
binding.pdfWebView.settings.allowFileAccess = true

viewModel.previewLiveData.observe(viewLifecycleOwner, EventObserver {
when (it) {
is PdfPreview.Success -> {
binding.pdfWebView.setInitialScale(it.info.initialZoom)
binding.pdfWebView.loadDataWithBaseURL(
"file:///android_asset/",
"<html><body><img src='${it.info.content}' /></body></html>",
"text/html",
"utf-8",
""
)
}

fun pdfBitmap(bitmaps: List<Bitmap>): Bitmap {
val width = bitmaps.first().width
val pageHeight = bitmaps.first().height
val height = bitmaps.first().height * bitmaps.size
val comboBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val comboImage = Canvas(comboBitmap)
bitmaps.forEachIndexed { index, bitmap ->
comboImage.drawBitmap(bitmap, 0f, (index * pageHeight).toFloat(), null)
}
is PdfPreview.Error -> {
navigateSafety(
PdfPreviewFragmentDirections.actionDialog(
data = DialogFragmentData(
title = R.string.dialog_error_title,
message = R.string.general_diskFull_body,
positiveButtonData = DialogButtonData.NavigateUp(R.string.ok)
)
)
)
}
}
})

return comboBitmap
viewModel.generatePreview(
screenWidth = resources.displayMetrics.widthPixels,
filesDir = requireContext().filesDir
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2023 De Staat der Nederlanden, Ministerie van Volksgezondheid, Welzijn en Sport.
* Licensed under the EUROPEAN UNION PUBLIC LICENCE v. 1.2
*
* SPDX-License-Identifier: EUPL-1.2
*
*/
package nl.rijksoverheid.ctr.holder.pdf

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import java.io.File
import kotlinx.coroutines.launch
import nl.rijksoverheid.ctr.shared.livedata.Event

abstract class PdfPreviewViewModel : ViewModel() {
val previewLiveData = MutableLiveData<Event<PdfPreview>>()
abstract fun generatePreview(screenWidth: Int, filesDir: File)
}

class PdfPreviewViewModelImpl(
private val previewPdfUseCase: PreviewPdfUseCase
) : PdfPreviewViewModel() {
override fun generatePreview(screenWidth: Int, filesDir: File) {
viewModelScope.launch {
val pdfPreviewResult = previewPdfUseCase.generatePreview(screenWidth, filesDir)
if (pdfPreviewResult != null) {
previewLiveData.postValue(Event(PdfPreview.Success(pdfPreviewResult)))
} else {
previewLiveData.postValue(Event(PdfPreview.Error))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class PdfWebViewFragment : BaseFragment(R.layout.fragment_pdf_webview) {
private val cachedAppConfigUseCase: CachedAppConfigUseCase by inject()

override fun onButtonClickWithRetryAction() {
// no retry
// there is no action to retry in this screen
}

override fun getFlow(): Flow {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package nl.rijksoverheid.ctr.holder.pdf

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.pdf.PdfRenderer
import android.os.ParcelFileDescriptor
import android.util.Base64
import java.io.ByteArrayOutputStream
import java.io.File
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

interface PreviewPdfUseCase {
suspend fun generatePreview(screenWidth: Int, filesDir: File): PDfPreviewInfo?
}

class PreviewPdfUseCaseImpl : PreviewPdfUseCase {
override suspend fun generatePreview(screenWidth: Int, filesDir: File): PDfPreviewInfo? {
return withContext(Dispatchers.IO) {
try {
val pdfFile = File(filesDir, PdfWebViewFragment.pdfFileName)
val parcelFileDescriptor =
ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY)
val pdfRenderer = PdfRenderer(parcelFileDescriptor)
val bitmaps = mutableListOf<Bitmap>()
for (i in 0 until pdfRenderer.pageCount) {
val currentPage = pdfRenderer.openPage(i)
val bitmap = Bitmap.createBitmap(
currentPage.width,
currentPage.height,
Bitmap.Config.ARGB_8888
)
currentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
bitmaps.add(bitmap)
currentPage.close()
}
pdfRenderer.close()

val bitmapWidth = bitmaps.first().width
val initialZoom = ((screenWidth.toFloat() / bitmapWidth.toFloat()) * 100).toInt()

PDfPreviewInfo(
content = pdfBitmap(bitmaps),
initialZoom = initialZoom
)
} catch (exception: Exception) {
null
}
}
}

private fun pdfBitmap(bitmaps: List<Bitmap>): String {
val width = bitmaps.first().width
val pageHeight = bitmaps.first().height
val height = bitmaps.first().height * bitmaps.size
val comboBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val comboImage = Canvas(comboBitmap)
bitmaps.forEachIndexed { index, bitmap ->
comboImage.drawBitmap(bitmap, 0f, (index * pageHeight).toFloat(), null)
}

val byteArrayOutputStream = ByteArrayOutputStream()
comboBitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)
val byteArray = byteArrayOutputStream.toByteArray()
return "data:image/png;base64,${Base64.encodeToString(byteArray, Base64.DEFAULT)}"
}
}
17 changes: 4 additions & 13 deletions holder/src/main/res/layout/fragment_pdf_preview.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent">

<ScrollView
android:id="@+id/scroll"
<WebView
android:id="@+id/pdfWebView"
android:importantForAccessibility="no"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true">

<ImageView
android:id="@+id/pdfImageView"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</ScrollView>
android:layout_height="match_parent" />

</nl.rijksoverheid.ctr.design.widgets.AnimatorConstraintLayout>
Loading

0 comments on commit 8123b35

Please sign in to comment.