Skip to content

Commit

Permalink
feat: render svg preview using webview
Browse files Browse the repository at this point in the history
  • Loading branch information
criticalAY committed Oct 12, 2024
1 parent 72c059e commit cd4d47b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.view.View
import android.webkit.WebView
import android.widget.ImageView
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts
Expand Down Expand Up @@ -68,6 +69,8 @@ import java.io.FileOutputStream
import java.io.IOException
import java.text.DecimalFormat

private const val SVG_IMAGE = "image/svg+xml"

@NeedsTest("Ensure correct option is executed i.e. gallery or camera")
class MultimediaImageFragment : MultimediaFragment(R.layout.fragment_multimedia_image) {
override val title: String
Expand Down Expand Up @@ -96,7 +99,6 @@ class MultimediaImageFragment : MultimediaFragment(R.layout.fragment_multimedia_
}

Activity.RESULT_OK -> {
view?.findViewById<TextView>(R.id.no_image_textview)?.visibility = View.GONE
val data = result.data
if (data == null) {
Timber.w("handleSelectImageIntent() no intent provided")
Expand Down Expand Up @@ -128,7 +130,6 @@ class MultimediaImageFragment : MultimediaFragment(R.layout.fragment_multimedia_
}

Activity.RESULT_OK -> {
view?.findViewById<TextView>(R.id.no_image_textview)?.visibility = View.GONE
val intent = result.data ?: return@registerForActivityResult
Timber.d("Intent not null, handling the result")
handleDrawingResult(intent)
Expand All @@ -154,7 +155,6 @@ class MultimediaImageFragment : MultimediaFragment(R.layout.fragment_multimedia_

isPictureTaken -> {
Timber.d("Image successfully captured")
view?.findViewById<TextView>(R.id.no_image_textview)?.visibility = View.GONE
handleTakePictureResult(viewModel.currentMultimediaPath.value)
}

Expand Down Expand Up @@ -274,7 +274,6 @@ class MultimediaImageFragment : MultimediaFragment(R.layout.fragment_multimedia_

private fun handleImageUri() {
if (imageUri != null) {
view?.findViewById<TextView>(R.id.no_image_textview)?.visibility = View.GONE
handleSelectImageIntent(imageUri)
} else {
handleSelectedImageOptions()
Expand Down Expand Up @@ -443,26 +442,35 @@ class MultimediaImageFragment : MultimediaFragment(R.layout.fragment_multimedia_

private fun handleSelectImageIntent(imageUri: Uri?) {
val mimeType = imageUri?.let { context?.contentResolver?.getType(it) }
if (mimeType == "image/svg+xml") {
Timber.i("Selected image is an SVG.")
view?.findViewById<TextView>(R.id.no_image_textview)?.apply {
text = resources.getString(R.string.multimedia_editor_svg_preview)
visibility = View.VISIBLE
}
} else {
// reset the no preview text
view?.findViewById<TextView>(R.id.no_image_textview)?.apply {
text = null
visibility = View.GONE
}
}

if (imageUri == null) {
Timber.w("handleSelectImageIntent() selectedImage was null")
showSomethingWentWrong()
return
}

if (mimeType == SVG_IMAGE) {
Timber.i("Selected image is an SVG.")

view?.findViewById<ImageView>(R.id.image_preview)?.visibility = View.GONE

view?.findViewById<WebView>(R.id.multimedia_webview)?.apply {
visibility = View.VISIBLE

imageUri.let { imageData ->
val svgData = loadSvgFromUri(imageData)
svgData?.let {
loadDataWithBaseURL(null, it, SVG_IMAGE, "UTF-8", null)
} ?: run {
Timber.w("Failed to load SVG from URI")
view?.findViewById<ImageView>(R.id.image_preview)?.setImageResource(R.drawable.ic_image_not_supported)
}
}
}
} else {
view?.findViewById<ImageView>(R.id.image_preview)?.visibility = View.VISIBLE
}

val internalizedPick = internalizeUri(imageUri)
if (internalizedPick == null) {
Timber.w(
Expand All @@ -488,6 +496,22 @@ class MultimediaImageFragment : MultimediaFragment(R.layout.fragment_multimedia_
imageCropperLauncher.launch(intent)
}

/**
* Loads an SVG file from the given URI and returns its content as a string.
*
* @param uri The URI of the SVG file to be loaded.
* @return The content of the SVG file as a string, or null if an error occurs.
*/
private fun loadSvgFromUri(uri: Uri): String? {
return try {
val inputStream = context?.contentResolver?.openInputStream(uri)
inputStream?.bufferedReader()?.use { it.readText() }
} catch (e: Exception) {
Timber.e(e, "Error reading SVG from URI")
null
}
}

private fun handleCropResultError(error: Exception) {
// cropImage can give us more information. Not sure it is actionable so for now just log it.
Timber.w(error, "cropImage threw an error")
Expand Down
13 changes: 5 additions & 8 deletions AnkiDroid/src/main/res/layout/fragment_multimedia_image.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,18 @@
app:layout_constraintBottom_toTopOf="@id/image_size_textview"
style="@style/CardView.PreviewerStyle" >

<TextView
android:id="@+id/no_image_textview"
android:paddingBottom="30dp"
android:gravity="center"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

<ImageView
android:src="@drawable/ic_image_not_supported"
android:id="@+id/image_preview"
android:scaleType="fitCenter"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

<WebView
android:id="@+id/multimedia_webview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</com.google.android.material.card.MaterialCardView>

<TextView
Expand Down
1 change: 0 additions & 1 deletion AnkiDroid/src/main/res/values/16-multimedia-editor.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@

<!-- not a good message, when an unexpected error happens -->
<string name="multimedia_editor_something_wrong">Something went wrong</string>
<string name="multimedia_editor_svg_preview">SVGs are not available for preview</string>
<string name="multimedia_editor_png_paste_error">Error converting clipboard image to png: %s</string>
<string name="multimedia_editor_attach_mm_content" comment="used for screen readers. Not visible to the user">Attach multimedia content to the %1$s field</string>

Expand Down

0 comments on commit cd4d47b

Please sign in to comment.