return of debug token for auth; ability to disable haptic and set logging level; etc

This commit is contained in:
2024-10-26 02:40:31 +03:00
parent ba43b6a940
commit babf20f62e
18 changed files with 204 additions and 59 deletions
@@ -18,6 +18,7 @@ import dev.meloda.fast.data.State
import dev.meloda.fast.data.processState
import dev.meloda.fast.datastore.UserSettings
import dev.meloda.fast.domain.ConversationsUseCase
import dev.meloda.fast.domain.LoadUserByIdUseCase
import dev.meloda.fast.domain.LongPollUpdatesParser
import dev.meloda.fast.domain.MessagesUseCase
import dev.meloda.fast.model.BaseError
@@ -65,6 +66,7 @@ interface ConversationsViewModel {
class ConversationsViewModelImpl(
updatesParser: LongPollUpdatesParser,
private val conversationsUseCase: ConversationsUseCase,
private val loadUserByIdUseCase: LoadUserByIdUseCase,
private val messagesUseCase: MessagesUseCase,
private val resources: Resources,
private val userSettings: UserSettings
@@ -97,6 +99,8 @@ class ConversationsViewModelImpl(
updatesParser.onConversationPinStateChanged(::handlePinStateChanged)
updatesParser.onInteractions(::handleInteraction)
loadProfile()
loadConversations()
}
@@ -223,6 +227,24 @@ class ConversationsViewModelImpl(
screenState.setValue { old -> old.copy(showOptions = newShowOptions) }
}
private fun loadProfile() {
loadUserByIdUseCase(userId = null)
.listenValue(viewModelScope) { state ->
state.processState(
error = { error ->
},
success = { response ->
val user = response ?: return@listenValue
screenState.setValue { old ->
old.copy(profileImageUrl = user.photo100)
}
}
)
}
}
private fun loadConversations(
offset: Int = currentOffset.value
) {
@@ -8,7 +8,8 @@ data class ConversationsScreenState(
val conversations: List<UiConversation>,
val isLoading: Boolean,
val isPaginating: Boolean,
val isPaginationExhausted: Boolean
val isPaginationExhausted: Boolean,
val profileImageUrl: String?
) {
companion object {
@@ -17,7 +18,8 @@ data class ConversationsScreenState(
conversations = emptyList(),
isLoading = true,
isPaginating = false,
isPaginationExhausted = false
isPaginationExhausted = false,
profileImageUrl = null
)
}
}
@@ -26,7 +26,7 @@ fun NavGraphBuilder.conversationsScreen(
ConversationsRoute(
onError = onError,
onConversationItemClicked = onConversationItemClicked,
onPhotoClicked = onPhotoClicked,
onConversationPhotoClicked = onPhotoClicked,
viewModel = viewModel
)
}
@@ -9,6 +9,7 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
@@ -19,17 +20,17 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material.icons.rounded.Refresh
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -51,6 +52,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
@@ -63,6 +65,7 @@ import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.core.view.HapticFeedbackConstantsCompat
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil.compose.AsyncImage
import coil.imageLoader
import coil.request.ImageRequest
import dev.chrisbanes.haze.haze
@@ -73,6 +76,7 @@ import dev.meloda.fast.conversations.ConversationsViewModel
import dev.meloda.fast.conversations.model.ConversationOption
import dev.meloda.fast.conversations.model.ConversationsScreenState
import dev.meloda.fast.conversations.model.UiConversation
import dev.meloda.fast.datastore.AppSettings
import dev.meloda.fast.datastore.UserSettings
import dev.meloda.fast.model.BaseError
import dev.meloda.fast.ui.components.ErrorView
@@ -90,7 +94,7 @@ import dev.meloda.fast.ui.R as UiR
fun ConversationsRoute(
onError: (BaseError) -> Unit,
onConversationItemClicked: (conversationId: Int) -> Unit,
onPhotoClicked: (url: String) -> Unit,
onConversationPhotoClicked: (url: String) -> Unit,
viewModel: ConversationsViewModel
) {
val context = LocalContext.current
@@ -129,7 +133,7 @@ fun ConversationsRoute(
onPaginationConditionsMet = viewModel::onPaginationConditionsMet,
onRefreshDropdownItemClicked = viewModel::onRefresh,
onRefresh = viewModel::onRefresh,
onPhotoClicked = onPhotoClicked
onConversationPhotoClicked = onConversationPhotoClicked
)
@@ -156,7 +160,7 @@ fun ConversationsScreen(
onPaginationConditionsMet: () -> Unit = {},
onRefreshDropdownItemClicked: () -> Unit = {},
onRefresh: () -> Unit = {},
onPhotoClicked: (url: String) -> Unit = {}
onConversationPhotoClicked: (url: String) -> Unit = {}
) {
val view = LocalView.current
val currentTheme = LocalThemeConfig.current
@@ -220,23 +224,32 @@ fun ConversationsScreen(
)
},
actions = {
IconButton(
onClick = {
dropDownMenuExpanded = true
}
) {
Icon(
imageVector = Icons.Outlined.MoreVert,
contentDescription = "Options button"
)
}
AsyncImage(
model = screenState.profileImageUrl,
contentDescription = "Profile Image",
modifier = Modifier
.padding(end = 12.dp)
.size(32.dp)
.clip(CircleShape)
.clickable { dropDownMenuExpanded = true },
placeholder = painterResource(id = UiR.drawable.ic_account_circle_cut)
)
// IconButton(
// onClick = {
// dropDownMenuExpanded = true
// }
// ) {
// Icon(
// imageVector = Icons.Outlined.MoreVert,
// contentDescription = "Options button"
// )
// }
DropdownMenu(
modifier = Modifier.defaultMinSize(minWidth = 140.dp),
expanded = dropDownMenuExpanded,
onDismissRequest = {
dropDownMenuExpanded = false
},
onDismissRequest = { dropDownMenuExpanded = false },
offset = DpOffset(x = (-4).dp, y = (-60).dp)
) {
DropdownMenuItem(
@@ -293,8 +306,9 @@ fun ConversationsScreen(
) {
FloatingActionButton(
onClick = {
view.performHapticFeedback(HapticFeedbackConstantsCompat.REJECT)
if (AppSettings.Debug.enableHaptic) {
view.performHapticFeedback(HapticFeedbackConstantsCompat.REJECT)
}
scope.launch {
for (i in 20 downTo 0 step 4) {
rotation.animateTo(
@@ -372,7 +386,7 @@ fun ConversationsScreen(
}.fillMaxSize(),
onOptionClicked = onOptionClicked,
padding = padding,
onPhotoClicked = onPhotoClicked
onPhotoClicked = onConversationPhotoClicked
)
}
}