Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load icons / Image Enhancement #3242

Merged
merged 21 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
bc43394
Adress image pr feedback.
Lentumunai-Mark May 8, 2024
2fea6f9
Merge branch 'main' of github.com:opensrp/fhircore into load-icons-en…
Lentumunai-Mark May 8, 2024
3ec80b4
spotless check fix.
Lentumunai-Mark May 8, 2024
66c7b13
Resolve PR feedback comments.
Lentumunai-Mark May 8, 2024
1a41704
Merge branch 'main' into load-icons-enhancement
Lentumunai-Mark May 8, 2024
b1ee2ca
Make some image properties like alpha, type to be configurable.
Lentumunai-Mark May 13, 2024
5616de9
Merge branch 'main' into load-icons-enhancement
Lentumunai-Mark May 13, 2024
9e8cbf2
Merge branch 'main' into load-icons-enhancement
Lentumunai-Mark May 14, 2024
e35b08d
Merge branch 'main' into load-icons-enhancement
dubdabasoduba May 14, 2024
ac59c84
Test out the recursive cases.
Lentumunai-Mark May 14, 2024
3fb6a9b
Merge branch 'load-icons-enhancement' of github.com:opensrp/fhircore …
Lentumunai-Mark May 14, 2024
e8b4667
Merge branch 'main' into load-icons-enhancement
Lentumunai-Mark May 14, 2024
39dd156
Merge branch 'main' into load-icons-enhancement
Lentumunai-Mark May 14, 2024
a4d1d70
Merge branch 'main' into load-icons-enhancement
ellykits May 14, 2024
822138f
Merge branch 'main' into load-icons-enhancement
Lentumunai-Mark May 14, 2024
4533510
Merge branch 'main' into load-icons-enhancement
Lentumunai-Mark May 14, 2024
ea71ea0
Merge branch 'main' into load-icons-enhancement
Lentumunai-Mark May 15, 2024
5266e23
Merge branch 'main' into load-icons-enhancement
Lentumunai-Mark May 16, 2024
d53f91f
Decode image data only once.
Lentumunai-Mark May 16, 2024
862c533
Merge branch 'load-icons-enhancement' of github.com:opensrp/fhircore …
Lentumunai-Mark May 16, 2024
6f8e6ff
Run spotless Apply.
Lentumunai-Mark May 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@ data class NavigationMenuConfig(
@Serializable
@Parcelize
data class ImageConfig(
val type: String = ICON_TYPE_LOCAL,
var type: String = ICON_TYPE_LOCAL,
val reference: String? = null,
val color: String? = null,
val alpha: Float = 1.0f,
val imageType: ImageType = ImageType.SVG,
val contentScale: ContentScaleType = ContentScaleType.FIT,
@Contextual var decodedBitmap: Bitmap? = null,
) : Parcelable, java.io.Serializable {
fun interpolate(computedValuesMap: Map<String, Any>): ImageConfig {
Expand All @@ -55,3 +58,18 @@ data class ImageConfig(

const val ICON_TYPE_LOCAL = "local"
const val ICON_TYPE_REMOTE = "remote"

enum class ImageType {
JPEG,
PNG,
SVG,
}

enum class ContentScaleType {
FIT,
CROP,
FILLHEIGHT,
INSIDE,
NONE,
FILLBOUNDS,
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import kotlin.time.Duration
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.hl7.fhir.r4.model.Binary
import org.hl7.fhir.r4.model.Enumerations
import org.hl7.fhir.r4.model.QuestionnaireResponse
import org.hl7.fhir.r4.model.ResourceType
Expand Down Expand Up @@ -68,7 +67,6 @@
import org.smartregister.fhircore.engine.util.SecureSharedPreference
import org.smartregister.fhircore.engine.util.SharedPreferenceKey
import org.smartregister.fhircore.engine.util.SharedPreferencesHelper
import org.smartregister.fhircore.engine.util.extension.decodeToBitmap
import org.smartregister.fhircore.engine.util.extension.extractLogicalIdUuid
import org.smartregister.fhircore.engine.util.extension.fetchLanguages
import org.smartregister.fhircore.engine.util.extension.getActivity
Expand All @@ -82,6 +80,7 @@
import org.smartregister.fhircore.quest.ui.report.measure.worker.MeasureReportMonthPeriodWorker
import org.smartregister.fhircore.quest.ui.shared.QuestionnaireHandler
import org.smartregister.fhircore.quest.ui.shared.models.QuestionnaireSubmission
import org.smartregister.fhircore.quest.util.extensions.decodeBinaryResourcesToBitmap
import org.smartregister.fhircore.quest.util.extensions.handleClickEvent
import org.smartregister.fhircore.quest.util.extensions.schedulePeriodically

Expand Down Expand Up @@ -131,14 +130,7 @@
it.menuIconConfig?.type == ICON_TYPE_REMOTE &&
!it.menuIconConfig!!.reference.isNullOrEmpty()
}
.forEach {
val resourceId = it.menuIconConfig!!.reference!!.extractLogicalIdUuid()
viewModelScope.launch(dispatcherProvider.io()) {
registerRepository.loadResource<Binary>(resourceId)?.let { binary ->
it.menuIconConfig!!.decodedBitmap = binary.data.decodeToBitmap()
}
}
}
.decodeBinaryResourcesToBitmap(viewModelScope, registerRepository)

Check warning on line 133 in android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/AppMainViewModel.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/AppMainViewModel.kt#L133

Added line #L133 was not covered by tests
}

suspend fun retrieveAppMainUiState(refreshAll: Boolean = true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,16 @@
import org.smartregister.fhircore.engine.domain.model.SnackBarMessageConfig
import org.smartregister.fhircore.engine.rulesengine.ResourceDataRulesExecutor
import org.smartregister.fhircore.engine.util.DispatcherProvider
import org.smartregister.fhircore.engine.util.extension.decodeToBitmap
import org.smartregister.fhircore.engine.util.extension.extractId
import org.smartregister.fhircore.engine.util.extension.extractLogicalIdUuid
import org.smartregister.fhircore.engine.util.extension.getActivity
import org.smartregister.fhircore.engine.util.fhirpath.FhirPathDataExtractor
import org.smartregister.fhircore.quest.R
import org.smartregister.fhircore.quest.ui.profile.bottomSheet.ProfileBottomSheetFragment
import org.smartregister.fhircore.quest.ui.profile.model.EligibleManagingEntity
import org.smartregister.fhircore.quest.util.extensions.decodeBinaryResourcesToBitmap
import org.smartregister.fhircore.quest.util.extensions.handleClickEvent
import org.smartregister.fhircore.quest.util.extensions.loadRemoteImagesBitmaps
import org.smartregister.fhircore.quest.util.extensions.toParamDataMap
import timber.log.Timber

Expand Down Expand Up @@ -97,14 +98,7 @@
)
profileConfig.overFlowMenuItems
.filter { it.icon != null && !it.icon!!.reference.isNullOrEmpty() }
.forEach {
val resourceId = it.icon!!.reference!!.extractLogicalIdUuid()
viewModelScope.launch(dispatcherProvider.io()) {
registerRepository.loadResource<Binary>(resourceId)?.let { binary ->
it.icon!!.decodedBitmap = binary.data.decodeToBitmap()
}
}
}
.decodeBinaryResourcesToBitmap(viewModelScope, registerRepository)

Check warning on line 101 in android/quest/src/main/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModel.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModel.kt#L101

Added line #L101 was not covered by tests
}

suspend fun retrieveProfileUiState(
Expand Down Expand Up @@ -142,6 +136,21 @@
computedValuesMap = resourceData.computedValuesMap.plus(paramsMap),
listResourceDataStateMap = listResourceDataStateMap,
)
if (
listResourceDataStateMap[listProperties.id] != null &&
listResourceDataStateMap[listProperties.id]?.size!! > 0
) {
val computedMap = listResourceDataStateMap[listProperties.id]?.get(0)?.computedValuesMap
viewModelScope.launch(dispatcherProvider.io()) {

Check warning on line 144 in android/quest/src/main/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModel.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModel.kt#L144

Added line #L144 was not covered by tests
if (computedMap != null) {
loadRemoteImagesBitmaps(

Check warning on line 146 in android/quest/src/main/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModel.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModel.kt#L146

Added line #L146 was not covered by tests
profileConfiguration.views,
registerRepository,
computedMap,

Check warning on line 149 in android/quest/src/main/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModel.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/ui/profile/ProfileViewModel.kt#L148-L149

Added lines #L148 - L149 were not covered by tests
)
}
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import org.hl7.fhir.r4.model.ResourceType
import org.smartregister.fhircore.engine.configuration.navigation.ContentScaleType
import org.smartregister.fhircore.engine.configuration.navigation.ICON_TYPE_LOCAL
import org.smartregister.fhircore.engine.configuration.navigation.ICON_TYPE_REMOTE
import org.smartregister.fhircore.engine.configuration.navigation.ImageConfig
import org.smartregister.fhircore.engine.configuration.navigation.ImageType
import org.smartregister.fhircore.engine.configuration.view.ImageProperties
import org.smartregister.fhircore.engine.configuration.view.ImageShape
import org.smartregister.fhircore.engine.domain.model.ResourceData
Expand Down Expand Up @@ -175,6 +177,11 @@
}
ICON_TYPE_REMOTE ->
if (imageConfig.decodedBitmap != null) {
val imageType = imageProperties.imageConfig?.imageType
val colorFilter =

Check warning on line 181 in android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/components/Image.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/components/Image.kt#L181

Added line #L181 was not covered by tests
if (imageType == ImageType.SVG || imageType == ImageType.PNG) tint else null
val contentScale =
convertContentScaleTypeToContentScale(imageProperties.imageConfig!!.contentScale)

Check warning on line 184 in android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/components/Image.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/components/Image.kt#L183-L184

Added lines #L183 - L184 were not covered by tests
Image(
modifier =
Modifier.testTag(SIDE_MENU_ITEM_REMOTE_ICON_TEST_TAG)
Expand All @@ -183,14 +190,28 @@
.fillMaxSize(0.9f),
bitmap = imageConfig.decodedBitmap!!.asImageBitmap(),
contentDescription = null,
contentScale = ContentScale.Crop,
colorFilter = ColorFilter.tint(tint ?: imageProperties.imageConfig?.color.parseColor()),
alpha = imageProperties.imageConfig!!.alpha,
contentScale = contentScale,

Check warning on line 194 in android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/components/Image.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/components/Image.kt#L193-L194

Added lines #L193 - L194 were not covered by tests
colorFilter = colorFilter?.let { ColorFilter.tint(it) },
)
}
}
}
}

fun convertContentScaleTypeToContentScale(
contentScale: ContentScaleType,
): ContentScale {
return when (contentScale) {
ContentScaleType.FIT -> ContentScale.Fit
ContentScaleType.CROP -> ContentScale.Crop
ContentScaleType.FILLHEIGHT -> ContentScale.Crop
ContentScaleType.INSIDE -> ContentScale.Inside
ContentScaleType.NONE -> ContentScale.None
ContentScaleType.FILLBOUNDS -> ContentScale.FillBounds

Check warning on line 211 in android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/components/Image.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/ui/shared/components/Image.kt#L206-L211

Added lines #L206 - L211 were not covered by tests
}
}

@PreviewWithBackgroundExcludeGenerated
@Composable
fun ImagePreview() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,28 @@
import androidx.core.os.bundleOf
import androidx.navigation.NavController
import androidx.navigation.NavOptions
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.hl7.fhir.r4.model.Binary
import org.smartregister.fhircore.engine.configuration.navigation.ICON_TYPE_REMOTE
import org.smartregister.fhircore.engine.configuration.navigation.NavigationMenuConfig
import org.smartregister.fhircore.engine.configuration.view.CardViewProperties
import org.smartregister.fhircore.engine.configuration.view.ColumnProperties
import org.smartregister.fhircore.engine.configuration.view.ImageProperties
import org.smartregister.fhircore.engine.configuration.view.ListProperties
import org.smartregister.fhircore.engine.configuration.view.RowProperties
import org.smartregister.fhircore.engine.configuration.view.ViewProperties
import org.smartregister.fhircore.engine.configuration.workflow.ActionTrigger
import org.smartregister.fhircore.engine.configuration.workflow.ApplicationWorkflow
import org.smartregister.fhircore.engine.data.local.register.RegisterRepository
import org.smartregister.fhircore.engine.domain.model.ActionConfig
import org.smartregister.fhircore.engine.domain.model.ActionParameter
import org.smartregister.fhircore.engine.domain.model.ActionParameterType
import org.smartregister.fhircore.engine.domain.model.OverflowMenuItemConfig
import org.smartregister.fhircore.engine.domain.model.ResourceData
import org.smartregister.fhircore.engine.domain.model.ViewType
import org.smartregister.fhircore.engine.util.extension.decodeJson
import org.smartregister.fhircore.engine.util.extension.decodeToBitmap
import org.smartregister.fhircore.engine.util.extension.encodeJson
import org.smartregister.fhircore.engine.util.extension.extractLogicalIdUuid
import org.smartregister.fhircore.engine.util.extension.interpolate
Expand Down Expand Up @@ -206,3 +220,78 @@
this?.asSequence()
?.filter { it.paramType == ActionParameterType.PARAMDATA }
?.associate { it.key to it.value } ?: emptyMap()

fun List<OverflowMenuItemConfig>.decodeBinaryResourcesToBitmap(
coroutineScope: CoroutineScope,
registerRepository: RegisterRepository,
) {
this.forEach {
val resourceId = it.icon!!.reference!!.extractLogicalIdUuid()
coroutineScope.launch() {

Check warning on line 230 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L228-L230

Added lines #L228 - L230 were not covered by tests
registerRepository.loadResource<Binary>(resourceId)?.let { binary ->
it.icon!!.decodedBitmap = binary.data.decodeToBitmap()

Check warning on line 232 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L232

Added line #L232 was not covered by tests
}
}
}
}

fun Sequence<NavigationMenuConfig>.decodeBinaryResourcesToBitmap(
coroutineScope: CoroutineScope,
registerRepository: RegisterRepository,
) {
this.forEach {
val resourceId = it.menuIconConfig!!.reference!!.extractLogicalIdUuid()
coroutineScope.launch() {

Check warning on line 244 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L242-L244

Added lines #L242 - L244 were not covered by tests
registerRepository.loadResource<Binary>(resourceId)?.let { binary ->
it.menuIconConfig!!.decodedBitmap = binary.data.decodeToBitmap()

Check warning on line 246 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L246

Added line #L246 was not covered by tests
}
}
}
}

suspend fun loadRemoteImagesBitmaps(
views: List<ViewProperties>,
registerRepository: RegisterRepository,
computedValuesMap: Map<String, Any>,
) {
suspend fun ViewProperties.loadIcons() {
when (this.viewType) {
ViewType.IMAGE -> {
val imageProps = this as ImageProperties

Check warning on line 260 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L260

Added line #L260 was not covered by tests
if (
!imageProps.imageConfig?.reference.isNullOrEmpty() &&
imageProps.imageConfig?.type == ICON_TYPE_REMOTE
) {
val resourceId =
imageProps.imageConfig!!
.reference!!
.interpolate(computedValuesMap)
.extractLogicalIdUuid()

Check warning on line 269 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L265-L269

Added lines #L265 - L269 were not covered by tests
registerRepository.loadResource<Binary>(resourceId)?.let { binary ->
imageProps.imageConfig?.decodedBitmap = binary.data.decodeToBitmap()
}
}
}
ViewType.ROW -> {
val container = this as RowProperties
container.children.forEach { it.loadIcons() }

Check warning on line 277 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L276-L277

Added lines #L276 - L277 were not covered by tests
}
ViewType.COLUMN -> {
val container = this as ColumnProperties
container.children.forEach { it.loadIcons() }

Check warning on line 281 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L280-L281

Added lines #L280 - L281 were not covered by tests
}
ViewType.CARD -> {
val card = this as CardViewProperties
card.content.forEach { it.loadIcons() }

Check warning on line 285 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L284-L285

Added lines #L284 - L285 were not covered by tests
}
ViewType.LIST -> {
val list = this as ListProperties
list.registerCard.views.forEach { it.loadIcons() }

Check warning on line 289 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L288-L289

Added lines #L288 - L289 were not covered by tests
}
else -> {
// Handle any other view types if needed
}
}
}
views.forEach { it.loadIcons() }

Check warning on line 296 in android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt

View check run for this annotation

Codecov / codecov/patch

android/quest/src/main/java/org/smartregister/fhircore/quest/util/extensions/ConfigExtensions.kt#L296

Added line #L296 was not covered by tests
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import java.util.Date
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.json.Json
import org.hl7.fhir.r4.model.Basic
import org.hl7.fhir.r4.model.Binary
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.DateType
import org.hl7.fhir.r4.model.Enumerations
Expand Down Expand Up @@ -58,6 +59,14 @@ object Faker {

private const val APP_DEBUG = "app/debug"

val sampleImageJSONString =
"{\n" +
" \"id\": \"d60ff460-7671-466a-93f4-c93a2ebf2077\",\n" +
" \"resourceType\": \"Binary\",\n" +
" \"contentType\": \"image/jpeg\",\n" +
" \"data\": \"iVBORw0KGgoAAAANSUhEUgAAAFMAAABTCAYAAADjsjsAAAAABHNCSVQICAgIfAhkiAAAABl0RVh0U29mdHdhcmUAZ25vbWUtc2NyZWVuc2hvdO8Dvz4AAAAtdEVYdENyZWF0aW9uIFRpbWUARnJpIDE5IEFwciAyMDI0IDA3OjIxOjM4IEFNIEVBVIqENmYAAADTSURBVHic7dDBCcAgAMBAdf/p+nQZXSIglLsJQube3xkk1uuAPzEzZGbIzJCZITNDZobMDJkZMjNkZsjMkJkhM0NmhswMmRkyM2RmyMyQmSEzQ2aGzAyZGTIzZGbIzJCZITNDZobMDJkZMjNkZsjMkJkhM0NmhswMmRkyM2RmyMyQmSEzQ2aGzAyZGTIzZGbIzJCZITNDZobMDJkZMjNkZsjMkJkhM0NmhswMmRkyM2RmyMyQmSEzQ2aGzAyZGTIzZGbIzJCZITNDZobMDJkZMjN0AXiwBCviCqIRAAAAAElFTkSuQmCC\"\n" +
"}"

fun buildTestConfigurationRegistry(): ConfigurationRegistry {
val fhirResourceService = mockk<FhirResourceService>()
val fhirResourceDataSource = spyk(FhirResourceDataSource(fhirResourceService))
Expand Down Expand Up @@ -150,4 +159,14 @@ object Faker {

override fun deviceOnline() = true
}

fun buildBinaryResource(
id: String = "d60ff460-7671-466a-93f4-c93a2ebf2077",
): Binary {
return Binary().apply {
this.id = id
this.contentType = "image/jpeg"
this.data = sampleImageJSONString.toByteArray()
}
}
}
Loading
Loading