Skip to content

Commit

Permalink
Refactor sync UI enhancement code
Browse files Browse the repository at this point in the history
* Refactor sync enhancement UI

Signed-off-by: Elly Kitoto <[email protected]>

* Fix position of fab when sync status bar is displayed

Signed-off-by: Elly Kitoto <[email protected]>

* Indicate when there is un-synced data

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor sync status bar for re-use

Signed-off-by: Elly Kitoto <[email protected]>

* Refactor package name

Signed-off-by: Elly Kitoto <[email protected]>

* Refresh map data on sync complete

Signed-off-by: Elly Kitoto <[email protected]>

* Fix rules execution

Signed-off-by: Elly Kitoto <[email protected]>

---------

Signed-off-by: Elly Kitoto <[email protected]>
Co-authored-by: Benjamin Mwalimu <[email protected]>
  • Loading branch information
ellykits and dubdabasoduba authored Aug 27, 2024
1 parent d088c4c commit 06b0de7
Show file tree
Hide file tree
Showing 18 changed files with 292 additions and 203 deletions.
2 changes: 1 addition & 1 deletion android/engine/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="sync">Sincronización manual</string>
<string name="manual_sync">Sincronización manual</string>
<string name="language">Idioma</string>
<string name="logout_as_user">Cerrar sesión como </string>
<string name="show_overdue">Mostrar vencido</string>
Expand Down
2 changes: 1 addition & 1 deletion android/engine/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="sync">Synchronisation manuelle</string>
<string name="manual_sync">Synchronisation manuelle</string>
<string name="language">Langue</string>
<string name="logout_as_user">Se déconnecter en tant que </string>
<string name="show_overdue">Afficher les retards</string>
Expand Down
2 changes: 1 addition & 1 deletion android/engine/src/main/res/values-in/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<resources>
<string name="sync">Sinkronisasi manual</string>
<string name="manual_sync">Sinkronisasi manual</string>
<string name="language">Bahasa</string>
<string name="logout_as_user">Keluar sebagai </string>
<string name="show_overdue">Tampilkan yang terlambat</string>
Expand Down
2 changes: 1 addition & 1 deletion android/engine/src/main/res/values-sw/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<string name="fully_vaccinated">"Chanjo kamili"</string>
<string name="select_language">Chagua Lugha</string>
<string name="register_new_client">Sajilisha mteja</string>
<string name="sync">Sawazisha</string>
<string name="manual_sync">Sawazisha</string>
<string name="show_overdue">Onyesha waliochelewa</string>
<string name="record_vaccine_nl">Rekodi\nChanjo</string>
<string name="str_save">Hifadhi</string>
Expand Down
4 changes: 3 additions & 1 deletion android/engine/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="sync">Manual Sync</string>
<string name="manual_sync">Manual Sync</string>
<string name="sync">Sync</string>
<string name="language">Language</string>
<string name="logout_as_user">Log out as </string>
<string name="show_overdue">Show overdue</string>
Expand Down Expand Up @@ -194,4 +195,5 @@
<string name="sync_down_inprogress"> %1$d%% Syncing down…</string>
<string name="default_html_title">file</string>
<string name="retry">RETRY</string>
<string name="unsynced_data_present">There\'s some un-synced data</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import com.mapbox.geojson.Feature
import com.mapbox.geojson.FeatureCollection
import com.mapbox.geojson.MultiPoint
Expand All @@ -48,7 +47,6 @@ import io.ona.kujaku.plugin.switcher.BaseLayerSwitcherPlugin
import io.ona.kujaku.plugin.switcher.layer.StreetsBaseLayer
import io.ona.kujaku.utils.CoordinateUtils
import io.ona.kujaku.views.KujakuMapView
import kotlinx.coroutines.launch
import org.jetbrains.annotations.VisibleForTesting
import org.json.JSONObject
import org.smartregister.fhircore.engine.configuration.geowidget.MapLayer
Expand Down Expand Up @@ -94,7 +92,9 @@ class GeoWidgetFragment : Fragment() {
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setupMapFeatures()
geoWidgetViewModel.features.observe(viewLifecycleOwner) { result ->
zoomToLocationsOnMap(result.map { it.toFeature() })
}
}

override fun onStart() {
Expand Down Expand Up @@ -132,14 +132,6 @@ class GeoWidgetFragment : Fragment() {
mapView.onSaveInstanceState(outState)
}

private fun setupMapFeatures() {
viewLifecycleOwner.lifecycleScope.launch {
geoWidgetViewModel.features.observe(viewLifecycleOwner) { result ->
zoomToLocationsOnMap(result.map { it.toFeature() })
}
}
}

private fun setupViews(): LinearLayout {
mapView = setUpMapView()
featureCollection =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.smartregister.fhircore.quest.ui.launcher
package org.smartregister.fhircore.quest.ui.geowidget

import android.os.Bundle
import android.view.LayoutInflater
Expand All @@ -26,7 +26,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -61,7 +60,6 @@ import org.smartregister.fhircore.engine.sync.SyncListenerManager
import org.smartregister.fhircore.engine.ui.base.AlertDialogue
import org.smartregister.fhircore.engine.ui.base.AlertIntent
import org.smartregister.fhircore.engine.ui.theme.AppTheme
import org.smartregister.fhircore.engine.util.DefaultDispatcherProvider
import org.smartregister.fhircore.engine.util.extension.showToast
import org.smartregister.fhircore.geowidget.model.GeoJsonFeature
import org.smartregister.fhircore.geowidget.screens.GeoWidgetFragment
Expand Down Expand Up @@ -92,7 +90,6 @@ class GeoWidgetLauncherFragment : Fragment(), OnSyncListener {

@Inject lateinit var configurationRegistry: ConfigurationRegistry

@Inject lateinit var dispatcherProvider: DefaultDispatcherProvider
private lateinit var geoWidgetFragment: GeoWidgetFragment
private lateinit var geoWidgetConfiguration: GeoWidgetConfiguration
private val navArgs by navArgs<GeoWidgetLauncherFragmentArgs>()
Expand Down Expand Up @@ -195,6 +192,9 @@ class GeoWidgetLauncherFragment : Fragment(), OnSyncListener {
}
}
},
isFirstTimeSync = geoWidgetLauncherViewModel.isFirstTime(),
appDrawerUIState = appDrawerUIState,
onAppMainEvent = appMainViewModel::onEvent,
)
}
}
Expand All @@ -209,24 +209,39 @@ class GeoWidgetLauncherFragment : Fragment(), OnSyncListener {
}

override fun onSync(syncJobStatus: CurrentSyncJobStatus) {
if (syncJobStatus is CurrentSyncJobStatus.Running) {
if (syncJobStatus.inProgressSyncJob is SyncJobStatus.InProgress) {
val inProgressSyncJob = syncJobStatus.inProgressSyncJob as SyncJobStatus.InProgress
val isSyncUpload = inProgressSyncJob.syncOperation == SyncOperation.UPLOAD
val progressPercentage = appMainViewModel.calculatePercentageProgress(inProgressSyncJob)
appMainViewModel.updateAppDrawerUIState(
isSyncUpload = isSyncUpload,
currentSyncJobStatus = syncJobStatus,
percentageProgress = progressPercentage,
)
when (syncJobStatus) {
is CurrentSyncJobStatus.Running -> {
if (syncJobStatus.inProgressSyncJob is SyncJobStatus.InProgress) {
val inProgressSyncJob = syncJobStatus.inProgressSyncJob as SyncJobStatus.InProgress
val isSyncUpload = inProgressSyncJob.syncOperation == SyncOperation.UPLOAD
val progressPercentage = appMainViewModel.calculatePercentageProgress(inProgressSyncJob)
appMainViewModel.updateAppDrawerUIState(
isSyncUpload = isSyncUpload,
currentSyncJobStatus = syncJobStatus,
percentageProgress = progressPercentage,
)
}
}
is CurrentSyncJobStatus.Succeeded,
is CurrentSyncJobStatus.Failed, -> {
lifecycleScope.launch {
val geoJsonFeatures =
geoWidgetLauncherViewModel.retrieveLocations(
geoWidgetConfig = geoWidgetConfiguration,
searchText = searchViewModel.searchQuery.value.query,
)
geoWidgetViewModel.features.postValue(geoJsonFeatures)
}
appMainViewModel.updateAppDrawerUIState(currentSyncJobStatus = syncJobStatus)
}
} else appMainViewModel.updateAppDrawerUIState(currentSyncJobStatus = syncJobStatus)
else -> appMainViewModel.updateAppDrawerUIState(currentSyncJobStatus = syncJobStatus)
}
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
showSetLocationDialog()
lifecycleScope.launch(dispatcherProvider.io()) {
lifecycleScope.launch {
// Retrieve if searchText is null; filter will be triggered automatically if text is not empty
if (searchViewModel.searchQuery.value.isBlank()) {
val geoJsonFeatures =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package org.smartregister.fhircore.quest.ui.launcher
package org.smartregister.fhircore.quest.ui.geowidget

import android.view.View
import android.widget.FrameLayout
Expand All @@ -37,7 +37,10 @@ import org.smartregister.fhircore.engine.domain.model.ToolBarHomeNavigation
import org.smartregister.fhircore.engine.util.extension.showToast
import org.smartregister.fhircore.quest.R
import org.smartregister.fhircore.quest.event.ToolbarClickEvent
import org.smartregister.fhircore.quest.ui.main.AppMainEvent
import org.smartregister.fhircore.quest.ui.main.components.TopScreenSection
import org.smartregister.fhircore.quest.ui.shared.components.SyncBottomBar
import org.smartregister.fhircore.quest.ui.shared.models.AppDrawerUIState
import org.smartregister.fhircore.quest.ui.shared.models.SearchQuery
import org.smartregister.fhircore.quest.util.extensions.handleClickEvent

Expand All @@ -52,6 +55,9 @@ fun GeoWidgetLauncherScreen(
geoWidgetConfiguration: GeoWidgetConfiguration,
searchQuery: MutableState<SearchQuery>,
search: (String) -> Unit,
isFirstTimeSync: Boolean,
appDrawerUIState: AppDrawerUIState,
onAppMainEvent: (AppMainEvent) -> Unit,
) {
val context = LocalContext.current
Scaffold(
Expand Down Expand Up @@ -91,6 +97,14 @@ fun GeoWidgetLauncherScreen(
}
}
},
bottomBar = {
SyncBottomBar(
isFirstTimeSync = isFirstTimeSync,
appDrawerUIState = appDrawerUIState,
onAppMainEvent = onAppMainEvent,
openDrawer = openDrawer,
)
},
) { innerPadding ->
Box(modifier = modifier.padding(innerPadding)) {
GeoWidgetFragmentView(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
* limitations under the License.
*/

package org.smartregister.fhircore.quest.ui.launcher
package org.smartregister.fhircore.quest.ui.geowidget

import android.content.Context
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
Expand All @@ -30,7 +29,10 @@ import org.hl7.fhir.r4.model.Enumerations
import org.hl7.fhir.r4.model.IdType
import org.hl7.fhir.r4.model.Location
import org.hl7.fhir.r4.model.ResourceType
import org.smartregister.fhircore.engine.configuration.ConfigType
import org.smartregister.fhircore.engine.configuration.ConfigurationRegistry
import org.smartregister.fhircore.engine.configuration.QuestionnaireConfig
import org.smartregister.fhircore.engine.configuration.app.ApplicationConfiguration
import org.smartregister.fhircore.engine.configuration.geowidget.GeoWidgetConfiguration
import org.smartregister.fhircore.engine.data.local.DefaultRepository
import org.smartregister.fhircore.engine.domain.model.ActionParameter
Expand All @@ -39,13 +41,13 @@ import org.smartregister.fhircore.engine.domain.model.RepositoryResourceData
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.SharedPreferenceKey
import org.smartregister.fhircore.engine.util.SharedPreferencesHelper
import org.smartregister.fhircore.engine.util.extension.extractLogicalIdUuid
import org.smartregister.fhircore.engine.util.extension.interpolate
import org.smartregister.fhircore.geowidget.model.GeoJsonFeature
import org.smartregister.fhircore.geowidget.model.Geometry
import org.smartregister.fhircore.quest.ui.shared.QuestionnaireHandler
import org.smartregister.fhircore.quest.ui.shared.models.AppDrawerUIState

@HiltViewModel
class GeoWidgetLauncherViewModel
Expand All @@ -55,17 +57,19 @@ constructor(
val dispatcherProvider: DispatcherProvider,
val sharedPreferencesHelper: SharedPreferencesHelper,
val resourceDataRulesExecutor: ResourceDataRulesExecutor,
val configurationRegistry: ConfigurationRegistry,
) : ViewModel() {

private val _snackBarStateFlow = MutableSharedFlow<SnackBarMessageConfig>()
val snackBarStateFlow = _snackBarStateFlow.asSharedFlow()

val appDrawerUiState = mutableStateOf(AppDrawerUIState())

private val _noLocationFoundDialog = MutableLiveData<Boolean>()
val noLocationFoundDialog: LiveData<Boolean>
get() = _noLocationFoundDialog

private val applicationConfiguration by lazy {
configurationRegistry.retrieveConfiguration<ApplicationConfiguration>(ConfigType.Application)
}
private lateinit var repositoryResourceDataList: List<RepositoryResourceData>

suspend fun retrieveLocations(
Expand Down Expand Up @@ -225,6 +229,11 @@ constructor(
_snackBarStateFlow.emit(snackBarMessageConfig)
}

fun isFirstTime(): Boolean =
sharedPreferencesHelper
.read(SharedPreferenceKey.LAST_SYNC_TIMESTAMP.name, null)
.isNullOrEmpty() && applicationConfiguration.usePractitionerAssignedLocationOnSync

private companion object {
const val KEY_LATITUDE = "positionLatitude"
const val KEY_LONGITUDE = "positionLongitude"
Expand Down
Loading

0 comments on commit 06b0de7

Please sign in to comment.