From 50342fb5a6492bf6c5c3a17a88b6a557cdd435aa Mon Sep 17 00:00:00 2001 From: Xavier Molloy <44061143+xavimolloy@users.noreply.github.com> Date: Wed, 24 Jan 2024 09:20:58 +0100 Subject: [PATCH] feat: [ANDROAPP-5830] update mobile UI version to 0.2-20240103.112017-2 (#3461) * fix: [ANDROAPP-5830] update mobile-ui version 0.2-20240103.112017-2 * feat: [ANDROAPP-5830] add to do's and bare minimun for compilation * ANDROAPP-5829-adapt-input-image-to-new-mobile-ui-functionality (#3462) * Handle `Intent.ACTION_SEND` in form view for sharing files * Open chooser intent when share button is clicked in `ImageInput` * Open chooser intent when share button is clicked in `InputSignature`` * Move `getBitmap` extension to commons module * Move `FormFileProvider` to commons module * Add image detail activity Currently we don't have a working "save image" functionality. So, it didn't make sense to copy the implementation that is not working. So for the time being I marked it as TODO * Launch `ImageDetailActivity` instead of `ImageDetailBottomDialog` * Remove `ImageDetailBottomDialog` * feat: [ANDROAPP-5848] Adapt Input dropdown to new functionality (#3465) * feat: [ANDROAPP-5848] remove old option set dialog, recycler event and deprecated code. refactor OptionSetConfiguration to default adapt input dropdown to new functionality * feat: [ANDROAPP-5848] remove deprecated code * fix: [ANDROAPP-5848] remove deprecated code * fix: [ANDROAPP-5848] ktlint fix * fix: [ANDROAPP-5848] dismiss keyboard on dismiss popup * fix: [ANDROAPP-5848] add old pop in again to maintain old form logic * feat: [ANDROAPP-5848] update mobile ui to version 0.2-20240123.112704-7 * fix: [ANDROAPP-5848] sonar fix * fix: [ANDROAPP-5848] sonar fix --------- Co-authored-by: Sasikanth Miriyampalli --- app/src/main/AndroidManifest.xml | 10 +- .../enrollment/EnrollmentActivity.kt | 14 +-- .../providers/InputFieldsProvider.kt | 104 +++++------------- .../eventDetails/ui/EventDetailsFragment.kt | 18 --- .../EventInitialRepositoryImpl.java | 1 - .../listView/SearchTEList.kt | 12 +- .../searchTrackEntity/mapView/SearchTEMap.kt | 17 ++- .../teidata/TEIDataFragment.kt | 24 ++-- commons/src/main/AndroidManifest.xml | 5 +- .../dhis2/commons}/data/FormFileProvider.kt | 2 +- .../imagedetail/ImageDetailActivity.kt | 75 +++++++++++++ .../imagedetail/ImageDetailBottomDialog.kt | 83 -------------- .../commons/extensions/PictureBindings.kt | 9 ++ .../workingLists/WorkingListChipGroup.kt | 4 +- commons/src/main/res/values/strings.xml | 1 + form/src/main/AndroidManifest.xml | 1 + .../dhis2/form/data/EnrollmentRepository.kt | 4 +- .../org/dhis2/form/data/EventRepository.kt | 4 +- .../form/model/OptionSetConfiguration.kt | 4 +- .../main/java/org/dhis2/form/ui/FormView.kt | 26 ++++- .../dhis2/form/ui/binding/PictureBindings.kt | 8 +- .../form/ui/dialog/QRDetailBottomDialog.kt | 2 +- .../provider/inputfield/DropdownProvider.kt | 99 ++++------------- .../provider/inputfield/ImageInputProvider.kt | 15 ++- .../provider/inputfield/SignatureProvider.kt | 11 +- gradle/libs.versions.toml | 2 +- 26 files changed, 235 insertions(+), 320 deletions(-) rename {form/src/main/java/org/dhis2/form => commons/src/main/java/org/dhis2/commons}/data/FormFileProvider.kt (88%) create mode 100644 commons/src/main/java/org/dhis2/commons/dialogs/imagedetail/ImageDetailActivity.kt delete mode 100644 commons/src/main/java/org/dhis2/commons/dialogs/imagedetail/ImageDetailBottomDialog.kt create mode 100644 commons/src/main/java/org/dhis2/commons/extensions/PictureBindings.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d3e5e952e1..0a64207c11 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -89,7 +89,9 @@ + android:configChanges="keyboardHidden|screenSize" + android:windowSoftInputMode="stateAlwaysHidden" + /> @@ -98,7 +100,7 @@ + android:windowSoftInputMode="stateAlwaysHidden" /> @@ -125,7 +127,7 @@ + android:windowSoftInputMode="adjustResize|stateAlwaysHidden" /> + android:windowSoftInputMode="adjustResize|stateAlwaysHidden" /> Unit, onClearCatCombo: (EventCategory) -> Unit, onOptionSelected: (CategoryOption?) -> Unit, required: Boolean = false, @@ -218,74 +207,31 @@ fun ProvideCategorySelector( ) } - var expanded by remember { mutableStateOf(false) } - - ExposedDropdownMenuBox( - expanded = expanded, - onExpandedChange = {}, - ) { - InputDropDown( - modifier = modifier, - title = category.name, - state = getInputState(detailsEnabled), - selectedItem = selectedItem, - onResetButtonClicked = { - selectedItem = null - onClearCatCombo(category) - }, - onArrowDropDownButtonClicked = { - expanded = !expanded - }, - isRequiredField = required, - ) - - if (expanded) { - if (category.optionsSize > DEFAULT_COUNT_LIMIT) { - onShowCategoryDialog(category) - expanded = false - } else { - DropdownMenu( - modifier = modifier.exposedDropdownSize(), - expanded = expanded, - onDismissRequest = { expanded = false }, - ) { - val selectableOptions = category.options - .filter { option -> - option.access().data().write() - }.filter { option -> - option.inDateRange(currentDate) - }.filter { option -> - option.inOrgUnit(selectedOrgUnit) - } - selectableOptions.forEach { option -> - val isSelected = option.displayName() == selectedItem - DropdownMenuItem( - modifier = Modifier.background( - when { - isSelected -> SurfaceColor.PrimaryContainer - else -> Color.Transparent - }, - ), - content = { - Text( - text = option.displayName() ?: option.code() ?: "", - color = when { - isSelected -> TextColor.OnPrimaryContainer - else -> TextColor.OnSurface - }, - ) - }, - onClick = { - expanded = false - selectedItem = option.displayName() - onOptionSelected(option) - }, - ) - } - } - } + val selectableOptions = category.options + .filter { option -> + option.access().data().write() + }.filter { option -> + option.inDateRange(currentDate) + }.filter { option -> + option.inOrgUnit(selectedOrgUnit) } - } + val dropdownItems = selectableOptions.map { DropdownItem(it.displayName() ?: it.code() ?: "") } + InputDropDown( + modifier = modifier, + title = category.name, + state = getInputState(detailsEnabled), + selectedItem = DropdownItem(selectedItem ?: ""), + onResetButtonClicked = { + selectedItem = null + onClearCatCombo(category) + }, + onItemSelected = { newSelectedDropdownItem -> + selectedItem = newSelectedDropdownItem.label + onOptionSelected(selectableOptions.firstOrNull { it.displayName() == newSelectedDropdownItem.label }) + }, + dropdownItems = dropdownItems, + isRequiredField = required, + ) } private fun getInputState(enabled: Boolean) = if (enabled) { diff --git a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsFragment.kt b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsFragment.kt index 74561abba0..5b50ec90b2 100644 --- a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsFragment.kt +++ b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventDetails/ui/EventDetailsFragment.kt @@ -39,7 +39,6 @@ import org.dhis2.databinding.EventDetailsFragmentBinding import org.dhis2.maps.views.MapSelectorActivity import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.injection.EventDetailsComponentProvider import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.injection.EventDetailsModule -import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.models.EventCategory import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.models.EventDetails import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.ProvideCategorySelector import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.ProvideCoordinates @@ -47,8 +46,6 @@ import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.Prov import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.ProvideOrgUnit import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.ProvideRadioButtons import org.dhis2.usescases.general.FragmentGlobalAbstract -import org.dhis2.utils.category.CategoryDialog -import org.dhis2.utils.category.CategoryDialog.Companion.TAG import org.dhis2.utils.customviews.PeriodDialog import org.hisp.dhis.android.core.common.FeatureType import org.hisp.dhis.android.core.enrollment.EnrollmentStatus @@ -179,9 +176,6 @@ class EventDetailsFragment : FragmentGlobalAbstract() { detailsEnabled = details.enabled, currentDate = date.currentDate, selectedOrgUnit = details.selectedOrgUnit, - onShowCategoryDialog = { - showCategoryDialog(it) - }, onClearCatCombo = { viewModel.onClearCatCombo() }, @@ -346,18 +340,6 @@ class EventDetailsFragment : FragmentGlobalAbstract() { showInfoDialog(getString(R.string.error), getString(R.string.no_org_units)) } - private fun showCategoryDialog(category: EventCategory) { - CategoryDialog( - CategoryDialog.Type.CATEGORY_OPTIONS, - category.uid, - true, - viewModel.eventDate.value.currentDate, - ) { categoryOption -> - val selectedOption = Pair(category.uid, categoryOption) - viewModel.setUpCategoryCombo(selectedOption) - }.show(requireActivity().supportFragmentManager, TAG) - } - private fun getEventCreationType(typeString: String?): EventCreationType { return typeString?.let { EventCreationType.valueOf(it) diff --git a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventInitial/EventInitialRepositoryImpl.java b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventInitial/EventInitialRepositoryImpl.java index 7b3d36fbf0..f9c53b58f1 100644 --- a/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventInitial/EventInitialRepositoryImpl.java +++ b/app/src/main/java/org/dhis2/usescases/eventsWithoutRegistration/eventInitial/EventInitialRepositoryImpl.java @@ -40,7 +40,6 @@ import java.util.Date; import java.util.List; -import io.reactivex.Completable; import io.reactivex.Flowable; import io.reactivex.Observable; import timber.log.Timber; diff --git a/app/src/main/java/org/dhis2/usescases/searchTrackEntity/listView/SearchTEList.kt b/app/src/main/java/org/dhis2/usescases/searchTrackEntity/listView/SearchTEList.kt index c585a11183..58d186a0e6 100644 --- a/app/src/main/java/org/dhis2/usescases/searchTrackEntity/listView/SearchTEList.kt +++ b/app/src/main/java/org/dhis2/usescases/searchTrackEntity/listView/SearchTEList.kt @@ -21,7 +21,7 @@ import androidx.paging.PagedList import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.RecyclerView import org.dhis2.bindings.dp -import org.dhis2.commons.dialogs.imagedetail.ImageDetailBottomDialog +import org.dhis2.commons.dialogs.imagedetail.ImageDetailActivity import org.dhis2.commons.filters.workingLists.WorkingListViewModel import org.dhis2.commons.filters.workingLists.WorkingListViewModelFactory import org.dhis2.commons.resources.ColorUtils @@ -35,7 +35,6 @@ import org.dhis2.usescases.searchTrackEntity.ui.CreateNewButton import org.dhis2.usescases.searchTrackEntity.ui.FullSearchButtonAndWorkingList import org.dhis2.usescases.searchTrackEntity.ui.mapper.TEICardMapper import org.dhis2.utils.isLandscape -import java.io.File import javax.inject.Inject const val ARG_FROM_RELATIONSHIP = "ARG_FROM_RELATIONSHIP" @@ -231,8 +230,13 @@ class SearchTEList : FragmentGlobalAbstract() { } private fun displayImageDetail(imagePath: String) { - ImageDetailBottomDialog(null, File(imagePath)) - .show(childFragmentManager, ImageDetailBottomDialog.TAG) + val intent = ImageDetailActivity.intent( + context = requireContext(), + title = null, + imagePath = imagePath, + ) + + startActivity(intent) } private fun observeNewData() { diff --git a/app/src/main/java/org/dhis2/usescases/searchTrackEntity/mapView/SearchTEMap.kt b/app/src/main/java/org/dhis2/usescases/searchTrackEntity/mapView/SearchTEMap.kt index 33b28e34d5..bd8ac8e108 100644 --- a/app/src/main/java/org/dhis2/usescases/searchTrackEntity/mapView/SearchTEMap.kt +++ b/app/src/main/java/org/dhis2/usescases/searchTrackEntity/mapView/SearchTEMap.kt @@ -14,7 +14,7 @@ import org.dhis2.animations.CarouselViewAnimations import org.dhis2.bindings.dp import org.dhis2.commons.bindings.clipWithRoundedCorners import org.dhis2.commons.data.RelationshipOwnerType -import org.dhis2.commons.dialogs.imagedetail.ImageDetailBottomDialog +import org.dhis2.commons.dialogs.imagedetail.ImageDetailActivity import org.dhis2.commons.locationprovider.LocationSettingLauncher import org.dhis2.commons.resources.ColorType import org.dhis2.commons.resources.ColorUtils @@ -33,7 +33,6 @@ import org.dhis2.usescases.searchTrackEntity.SearchTEIViewModel import org.dhis2.usescases.searchTrackEntity.SearchTeiViewModelFactory import org.dhis2.utils.NetworkUtils import org.dhis2.utils.isPortrait -import java.io.File import javax.inject.Inject const val ARG_FROM_RELATIONSHIP = "ARG_FROM_RELATIONSHIP" @@ -259,14 +258,14 @@ class SearchTEMap : FragmentGlobalAbstract(), MapboxMap.OnMapClickListener { true } .addOnProfileImageClickListener { path: String? -> - if (binding.mapCarousel.carouselEnabled) { - ImageDetailBottomDialog( - null, - File(path), - ).show( - childFragmentManager, - ImageDetailBottomDialog.TAG, + if (binding.mapCarousel.carouselEnabled && !path.isNullOrBlank()) { + val intent = ImageDetailActivity.intent( + context = requireContext(), + title = null, + imagePath = path, ) + + startActivity(intent) } Unit } diff --git a/app/src/main/java/org/dhis2/usescases/teiDashboard/dashboardfragments/teidata/TEIDataFragment.kt b/app/src/main/java/org/dhis2/usescases/teiDashboard/dashboardfragments/teidata/TEIDataFragment.kt index 78d3e1941b..22e458dbf3 100644 --- a/app/src/main/java/org/dhis2/usescases/teiDashboard/dashboardfragments/teidata/TEIDataFragment.kt +++ b/app/src/main/java/org/dhis2/usescases/teiDashboard/dashboardfragments/teidata/TEIDataFragment.kt @@ -31,7 +31,7 @@ import org.dhis2.commons.data.EventViewModel import org.dhis2.commons.data.StageSection import org.dhis2.commons.dialogs.CustomDialog import org.dhis2.commons.dialogs.DialogClickListener -import org.dhis2.commons.dialogs.imagedetail.ImageDetailBottomDialog +import org.dhis2.commons.dialogs.imagedetail.ImageDetailActivity import org.dhis2.commons.filters.FilterItem import org.dhis2.commons.filters.FilterManager import org.dhis2.commons.filters.FilterManager.PeriodRequest @@ -269,10 +269,13 @@ class TEIDataFragment : FragmentGlobalAbstract(), TEIDataContracts.View { val card = teiDashboardCardMapper.map( dashboardModel = dashboardModel, onImageClick = { fileToShow -> - ImageDetailBottomDialog( - null, - fileToShow, - ).show(childFragmentManager, ImageDetailBottomDialog.TAG) + val intent = ImageDetailActivity.intent( + context = requireActivity(), + title = null, + imagePath = fileToShow.path, + ) + + startActivity(intent) }, phoneCallback = { openChooser(it, Intent.ACTION_DIAL) }, emailCallback = { openChooser(it, Intent.ACTION_SENDTO) }, @@ -537,10 +540,13 @@ class TEIDataFragment : FragmentGlobalAbstract(), TEIDataContracts.View { binding.cardFront.teiImage.setOnClickListener { val fileToShow = File(filePath) if (fileToShow.exists()) { - ImageDetailBottomDialog( - null, - fileToShow, - ).show(childFragmentManager, ImageDetailBottomDialog.TAG) + val intent = ImageDetailActivity.intent( + context = requireActivity(), + title = null, + imagePath = fileToShow.path, + ) + + startActivity(intent) } } } diff --git a/commons/src/main/AndroidManifest.xml b/commons/src/main/AndroidManifest.xml index d1a58dce21..6c8c73cf91 100644 --- a/commons/src/main/AndroidManifest.xml +++ b/commons/src/main/AndroidManifest.xml @@ -16,6 +16,9 @@ android:name="org.dhis2.commons.featureconfig.ui.FeatureConfigView" android:exported="false"/> + + - \ No newline at end of file + diff --git a/form/src/main/java/org/dhis2/form/data/FormFileProvider.kt b/commons/src/main/java/org/dhis2/commons/data/FormFileProvider.kt similarity index 88% rename from form/src/main/java/org/dhis2/form/data/FormFileProvider.kt rename to commons/src/main/java/org/dhis2/commons/data/FormFileProvider.kt index f62191993e..e807a84461 100644 --- a/form/src/main/java/org/dhis2/form/data/FormFileProvider.kt +++ b/commons/src/main/java/org/dhis2/commons/data/FormFileProvider.kt @@ -1,4 +1,4 @@ -package org.dhis2.form.data +package org.dhis2.commons.data import android.content.Context diff --git a/commons/src/main/java/org/dhis2/commons/dialogs/imagedetail/ImageDetailActivity.kt b/commons/src/main/java/org/dhis2/commons/dialogs/imagedetail/ImageDetailActivity.kt new file mode 100644 index 0000000000..5d0a0e9594 --- /dev/null +++ b/commons/src/main/java/org/dhis2/commons/dialogs/imagedetail/ImageDetailActivity.kt @@ -0,0 +1,75 @@ +package org.dhis2.commons.dialogs.imagedetail + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.activity.compose.setContent +import androidx.appcompat.app.AppCompatActivity +import androidx.compose.runtime.remember +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.graphics.painter.BitmapPainter +import androidx.core.content.FileProvider +import org.dhis2.commons.R +import org.dhis2.commons.data.FormFileProvider +import org.dhis2.commons.extensions.getBitmap +import org.hisp.dhis.mobile.ui.designsystem.component.FullScreenImage +import timber.log.Timber +import java.io.File +import java.io.IOException + +class ImageDetailActivity : AppCompatActivity() { + + companion object { + + private const val ARG_IMAGE_TITLE = "arg_image_title" + private const val ARG_IMAGE_PATH = "arg_image_path" + + fun intent(context: Context, title: String?, imagePath: String): Intent { + return Intent(context, ImageDetailActivity::class.java).apply { + putExtra(ARG_IMAGE_TITLE, title) + putExtra(ARG_IMAGE_PATH, imagePath) + } + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val title = intent.getStringExtra(ARG_IMAGE_TITLE) + val imagePath = intent.getStringExtra(ARG_IMAGE_PATH)!! + + setContent { + val painter = remember(imagePath) { + imagePath.getBitmap()?.let { BitmapPainter(it.asImageBitmap()) } + } + + FullScreenImage( + painter = painter!!, + title = title.orEmpty(), + onDismiss = { finish() }, + onDownloadButtonClick = { }, + onShareButtonClick = { shareImage(imagePath) }, + ) + } + } + + private fun shareImage(image: String) { + val intent = Intent(Intent.ACTION_SEND).apply { + val contentUri = FileProvider.getUriForFile( + this@ImageDetailActivity, + FormFileProvider.fileProviderAuthority, + File(image), + ) + setDataAndType(contentUri, contentResolver.getType(contentUri)) + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + putExtra(Intent.EXTRA_STREAM, contentUri) + } + + val title = resources.getString(R.string.open_with) + val chooser = Intent.createChooser(intent, title) + try { + startActivity(chooser) + } catch (e: IOException) { + Timber.e(e) + } + } +} diff --git a/commons/src/main/java/org/dhis2/commons/dialogs/imagedetail/ImageDetailBottomDialog.kt b/commons/src/main/java/org/dhis2/commons/dialogs/imagedetail/ImageDetailBottomDialog.kt deleted file mode 100644 index 09a95bd288..0000000000 --- a/commons/src/main/java/org/dhis2/commons/dialogs/imagedetail/ImageDetailBottomDialog.kt +++ /dev/null @@ -1,83 +0,0 @@ -package org.dhis2.commons.dialogs.imagedetail - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.FrameLayout -import androidx.databinding.DataBindingUtil -import com.bumptech.glide.Glide -import com.bumptech.glide.load.engine.DiskCacheStrategy -import com.bumptech.glide.load.resource.bitmap.RoundedCorners -import com.bumptech.glide.request.RequestOptions -import com.google.android.material.bottomsheet.BottomSheetBehavior -import com.google.android.material.bottomsheet.BottomSheetDialog -import com.google.android.material.bottomsheet.BottomSheetDialogFragment -import org.dhis2.commons.R -import org.dhis2.commons.bindings.dp -import org.dhis2.commons.bindings.widthAndHeight -import org.dhis2.commons.databinding.DetailImageBottomDialogBinding -import org.dhis2.commons.resources.ColorType -import org.dhis2.commons.resources.ColorUtils -import java.io.File - -class ImageDetailBottomDialog( - val label: String?, - private val fileToShow: File, -) : BottomSheetDialogFragment() { - companion object { - const val TAG: String = "IMG_DETAIL_DIALOG" - } - - private lateinit var binding: DetailImageBottomDialogBinding - - val colorUtils: ColorUtils = ColorUtils() - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - binding = - DataBindingUtil.inflate(inflater, R.layout.detail_image_bottom_dialog, container, false) - binding.title = label - binding.closeButton.setImageDrawable( - colorUtils.tintDrawableWithColor( - binding.closeButton.drawable, - colorUtils.getPrimaryColor(requireContext(), ColorType.PRIMARY), - ), - ) - binding.closeButton.setOnClickListener { dismiss() } - - return binding.root - } - - // This is necessary to show the bottomSheet dialog with full height on landscape - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - view.viewTreeObserver.addOnGlobalLayoutListener { - val dialog = dialog as BottomSheetDialog - - val bottomSheet = - dialog.findViewById( - com.google.android.material.R.id.design_bottom_sheet, - ) - val behavior = BottomSheetBehavior.from(bottomSheet!!) - behavior.state = BottomSheetBehavior.STATE_EXPANDED - behavior.setPeekHeight(0) - } - } - - override fun onResume() { - super.onResume() - val (width, height) = fileToShow.widthAndHeight(300.dp) - Glide.with(this) - .load(fileToShow) - .apply(RequestOptions.skipMemoryCacheOf(true)) - .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.NONE)) - .apply(RequestOptions.bitmapTransform(RoundedCorners(40))) - .apply(RequestOptions().override(width, height)) - .skipMemoryCache(true) - .into(binding.fullImage) - } -} diff --git a/commons/src/main/java/org/dhis2/commons/extensions/PictureBindings.kt b/commons/src/main/java/org/dhis2/commons/extensions/PictureBindings.kt new file mode 100644 index 0000000000..88bf020036 --- /dev/null +++ b/commons/src/main/java/org/dhis2/commons/extensions/PictureBindings.kt @@ -0,0 +1,9 @@ +package org.dhis2.commons.extensions + +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import java.io.File + +fun String.getBitmap(): Bitmap? = File(this) + .takeIf { it.exists() } + ?.let { BitmapFactory.decodeFile(it.absolutePath) } diff --git a/commons/src/main/java/org/dhis2/commons/filters/workingLists/WorkingListChipGroup.kt b/commons/src/main/java/org/dhis2/commons/filters/workingLists/WorkingListChipGroup.kt index 176adc638f..125ea08aed 100644 --- a/commons/src/main/java/org/dhis2/commons/filters/workingLists/WorkingListChipGroup.kt +++ b/commons/src/main/java/org/dhis2/commons/filters/workingLists/WorkingListChipGroup.kt @@ -21,7 +21,7 @@ import org.dhis2.commons.databinding.ItemFilterWorkingListChipBinding import org.dhis2.commons.filters.FilterManager import org.dhis2.commons.filters.WorkingListFilter import org.dhis2.commons.filters.data.EmptyWorkingList -import org.hisp.dhis.mobile.ui.designsystem.component.Chip +import org.hisp.dhis.mobile.ui.designsystem.component.FilterChip import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing class WorkingListChipGroup @JvmOverloads constructor( @@ -88,7 +88,7 @@ fun WorkingListChipGroup( workingListFilterState.value?.let { workingListFilter -> LazyRow(modifier) { itemsIndexed(workingListFilter.workingLists) { index, workingList -> - Chip( + FilterChip( modifier = Modifier.padding( start = if (index == 0) Spacing.Spacing16 else Spacing.Spacing0, end = if (index == workingListFilter.workingLists.size - 1) { diff --git a/commons/src/main/res/values/strings.xml b/commons/src/main/res/values/strings.xml index 7a4741b683..537fd500d8 100644 --- a/commons/src/main/res/values/strings.xml +++ b/commons/src/main/res/values/strings.xml @@ -239,4 +239,5 @@ %d year overdue %d years overdue + Open with diff --git a/form/src/main/AndroidManifest.xml b/form/src/main/AndroidManifest.xml index d63ef3cb31..7a7f0d1e0a 100644 --- a/form/src/main/AndroidManifest.xml +++ b/form/src/main/AndroidManifest.xml @@ -15,6 +15,7 @@ diff --git a/form/src/main/java/org/dhis2/form/data/EnrollmentRepository.kt b/form/src/main/java/org/dhis2/form/data/EnrollmentRepository.kt index 7fc03cc015..03e3dd0b91 100644 --- a/form/src/main/java/org/dhis2/form/data/EnrollmentRepository.kt +++ b/form/src/main/java/org/dhis2/form/data/EnrollmentRepository.kt @@ -175,9 +175,7 @@ class EnrollmentRepository( if (!optionSet.isNullOrEmpty()) { val optionCount = d2.optionModule().options().byOptionSetUid().eq(optionSet).blockingCount() - optionSetConfig = OptionSetConfiguration.config( - optionCount, - ) { + optionSetConfig = OptionSetConfiguration.config(optionCount) { d2.optionModule().options().byOptionSetUid().eq(optionSet) .orderBySortOrder(RepositoryScope.OrderByDirection.ASC) .blockingGet() diff --git a/form/src/main/java/org/dhis2/form/data/EventRepository.kt b/form/src/main/java/org/dhis2/form/data/EventRepository.kt index 09414a55c3..d452cf7d0b 100644 --- a/form/src/main/java/org/dhis2/form/data/EventRepository.kt +++ b/form/src/main/java/org/dhis2/form/data/EventRepository.kt @@ -146,9 +146,7 @@ class EventRepository( val optionCount = d2.optionModule().options().byOptionSetUid().eq(optionSet) .blockingCount() - optionSetConfig = OptionSetConfiguration.config( - optionCount, - ) { + optionSetConfig = OptionSetConfiguration.config(optionCount) { d2.optionModule().options().byOptionSetUid().eq(optionSet) .orderBySortOrder(RepositoryScope.OrderByDirection.ASC).blockingGet() } diff --git a/form/src/main/java/org/dhis2/form/model/OptionSetConfiguration.kt b/form/src/main/java/org/dhis2/form/model/OptionSetConfiguration.kt index 77607a14e7..2b80108554 100644 --- a/form/src/main/java/org/dhis2/form/model/OptionSetConfiguration.kt +++ b/form/src/main/java/org/dhis2/form/model/OptionSetConfiguration.kt @@ -18,9 +18,11 @@ sealed class OptionSetConfiguration( ) data class BigOptionSet( + override val options: List