В верхней панели у меня есть кнопка, и я хочу, чтобы при нажатии на нее открывался ModalBottomSheet для воспроизведения текста, связанного с содержимым, которое в данный момент отображается на экране.
Моя проблема в том, что я не знаю, как получить этот текст или где лучше всего это сделать это, применяя чистую архитектуру.
Прошу прощения за многословие, но я хочу объяснить контекст как можно яснее.
Изначально , я показываю, как
Код: Выделить всё
uiState
Код: Выделить всё
@HiltViewModel
class UniversalisViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
val userDataRepository: UserDataRepository,
getTopicWithDate: GetUniversalisUseCase,
) : ViewModel() {
//...
val uiState: StateFlow = combine(
selectedTopicId,
getTopicWithDate(
sortBy = HomeSortField.ID,
date = Utils.hoy.toInt(),
topicId = selectedTopicId.value!!.toInt()
),
UniversalisUiState::UniversalisData,
).stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = UniversalisUiState.Loading,
)
//...
}
sealed interface UniversalisUiState {
data object Loading : UniversalisUiState
data object Error : UniversalisUiState
data class UniversalisData(
val selectedTopicId: String?,
val topics: List,
) : UniversalisUiState
data object Empty : UniversalisUiState
}
Код: Выделить всё
fun UniversalisRoute(
showBackButton: Boolean,
onBackClick: () -> Unit,
modifier: Modifier = Modifier,
viewModel: UniversalisViewModel = hiltViewModel(),
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
UniversalisScreen(
uiState = uiState,
modifier = modifier,
onReaderClick = viewModel::onReaderClick,
onBackClick = onBackClick,
)
//
}
Код: Выделить всё
UniversalisScreen
Это часть UniversalisScreen, которая отображает данные на экране:
Код: Выделить всё
if (uiState.topics.isNotEmpty()) {
universalisBody(
name = Utils.capitalize(LiturgyHelper.liturgyByType(uiState.selectedTopicId!!.toInt())),
description = uiState.topics[0].data[0].fecha,
universalis = uiState,
)
}
Код: Выделить всё
private fun LazyListScope.universalisBody(
name: String,
description: String,
universalis: UniversalisUiState.UniversalisData,
) {
item {
UniversalisHeader(name, description)
}
universalisResourceCards(universalis)
}
Код: Выделить всё
private fun LazyListScope.universalisResourceCards(
universalis: UniversalisUiState,
) {
when (universalis) {
is UniversalisUiState.UniversalisData -> {
universalisResourceCardItems(
items = universalis.topics,
topicId = universalis.selectedTopicId,
itemModifier = Modifier.padding(24.dp),
)
}
// ...
}
}
Код: Выделить всё
@Composable
fun UniversalisResourceCardExpanded(
universalisResource: List,
modifier: Modifier = Modifier,
topicId: String?,
) {
Card(
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
) {
Column {
Box(
modifier = Modifier.padding(16.dp),
) {
Column {
Spacer(modifier = Modifier.height(12.dp))
Row {
var title: String
topicId!!.toInt().let {
title = when {
it == 20 -> {
val sancti = universalisResource[0].data[0].liturgia!!.liturgiaTypus as Alteri.Sancti
sancti.sanctus.monthName
}
else -> {
universalisResource[0].data[0].liturgia!!.tempus!!.externus.toString()
}
}
}
UniversalisResourceTitle(
title,
modifier = Modifier.fillMaxWidth((.8f)),
)
Spacer(modifier = Modifier.weight(1f))
}
Spacer(modifier = Modifier.height(14.dp))
Row(verticalAlignment = Alignment.CenterVertically) {
UniversalisResourceMetaData(universalisResource[0].data[0].liturgia!!.nomen)
}
Spacer(modifier = Modifier.height(14.dp))
var data = universalisResource[0].data[0]
Universalis(data, topicId = topicId, universalisResource[0].dynamic)
}
}
}
}
}
Код: Выделить всё
Universalis(data, topicId = topicId, universalisResource[0].dynamic)
Код: Выделить всё
@Composable
fun Universalis(data: Universalis, topicId: String?, userData: UserDataDynamic) {
val itemId = topicId!!.toInt()
val onTap = { point: Offset -> }
if (data.liturgia!!.liturgiaTypus is Sortable) {
data.liturgia!!.liturgiaTypus?.sort()
}
/*
This is a test, which works.
What I need is to call the screen that will read TTS
in a ModalBottomSheet, when the button that is loaded
from the start in AppState is pressed.
*/
if (userData.useVoiceReader) {
TextToSpeechScreen(data.getAllForRead())
}
/*
These are the different screens that the user will see,
depending on the type of data parameter
*/
when (itemId) {
1 -> MixtusScreen(
data = data.liturgia!!.liturgiaTypus as LHMixtus,
calendarTime = data.timeFK,
userData = userData,
onTap = onTap
)
2 -> OfficiumScreen(
data = data.liturgia!!.liturgiaTypus as LHOfficium,
calendarTime = data.timeFK,
userData = userData,
onTap = onTap
)
//
}
}
Попытка, которую я предпринял, чтобы отобразить ModalBottomSheet< /code> при нажатии на кнопку действие с событием onReaderClick передавалось на верхнюю панель.
Код: Выделить всё
NiaTopAppBar(
// ...
readerIcon = NiaIcons.Reader,
onReaderClick = {
showBottomSheet = true
appState.textToRead //I can see "Lorem ipsum" here
},
)
Код: Выделить всё
@Stable
class NiaAppState(
val navController: NavHostController,
coroutineScope: CoroutineScope,
val windowSizeClass: WindowSizeClass,
networkMonitor: NetworkMonitor,
universalisRepository: UniversalisRepository,
timeZoneMonitor: TimeZoneMonitor,
) {
//...
val shouldRead = universalisRepository.getReader()
}
Код: Выделить всё
override fun getReader():String{
return "Lorem ipsum"
}
Моя проблема в том, что я не знаю, как это сделать, применяя чистую архитектуру в стиле Compose.
Подробнее здесь: https://stackoverflow.com/questions/789 ... m-appstate