Migrate Offline Area Screens to Compose - #3915
Conversation
- Replace offline_area_selector_frag.xml with Compose OfflineAreaSelectorScreen - Convert LiveData to StateFlow with OfflineAreaSelectorState and OfflineAreaSelectorEvent - Inline and modernize DownloadProgressDialog inside OfflineAreaSelectorScreen - Remove legacy viewport outline drawable - Add comprehensive Compose UI and ViewModel unit tests
- Replace offline_area_viewer_frag.xml with Compose OfflineAreaViewerScreen - Convert LiveData to StateFlow with OfflineAreaViewerState - Modernize deletion flow and progress overlay in Compose - Add comprehensive Compose UI and ViewModel unit tests
- Replace offline_areas_frag.xml with Compose OfflineAreasScreen - Convert LiveData to StateFlow with OfflineAreasState - Inline and modernize OfflineAreaListItem inside OfflineAreasScreen - Clean up obsolete layouts, styles, and dimensions - Add comprehensive Compose UI and ViewModel unit tests
| Box(modifier = modifier.fillMaxSize()) { | ||
| Column(modifier = Modifier.fillMaxSize()) { | ||
| Toolbar( | ||
| stringRes = R.string.offline_area_selector_title, |
There was a problem hiding this comment.
nit: the title in the toolbar was previously centered and now it is left aligned
| } | ||
|
|
||
| @Composable | ||
| fun DownloadProgressDialog( |
There was a problem hiding this comment.
shouldn't this also be annotated with @VisibleForTesting?
| offlineAreaRepository.removeFromDevice(deletedArea) | ||
| _uiState.update { it.copy(isProgressOverlayVisible = false, area = null) } | ||
| navigateUpChannel.send(Unit) | ||
| } catch (e: kotlinx.coroutines.CancellationException) { |
There was a problem hiding this comment.
nit: import could be simplified
| Timber.e(e, "Failed to remove offline area") | ||
| _uiState.update { it.copy(isProgressOverlayVisible = false) } |
There was a problem hiding this comment.
it's a nice improvement to have exception handling in this flow now. There is no user feedback in this error case though, maybe we can add an error toast with a generic string (eg. R.string.unexpected_error)?
| modifier = modifier.fillMaxSize(), | ||
| topBar = { | ||
| Toolbar( | ||
| stringRes = R.string.offline_map_imagery, |
There was a problem hiding this comment.
same comment here regarding centering the toolbar title
| imageVector = ImageVector.vectorResource(id = R.drawable.ic_offline_pin), | ||
| contentDescription = stringResource(id = R.string.offline_area_list_item_icon), | ||
| tint = MaterialTheme.colorScheme.primary, | ||
| modifier = Modifier.size(24.dp), |
There was a problem hiding this comment.
nit: consider extracting some reusable dimensions/paddings in these files to Size.kt
| } | ||
|
|
||
| @Composable | ||
| private fun OfflineAreaSelectorButtons( |

Towards #1795
Migrates the offline area screens (selector screen, viewer screen & list offline areas screen) from XML to compose layout.
Before:
Screen_recording_20260901_144819.webm
After:
Screen_recording_20260901_144321.webm
@andreia-ferreira PTAL?