ConversationListScreen: Implements pull-to-refresh
This commit is contained in:
@@ -9,11 +9,16 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Info
|
||||
import androidx.compose.material.icons.rounded.Settings
|
||||
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
||||
import androidx.compose.material.pullrefresh.pullRefresh
|
||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
@@ -25,10 +30,10 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import net.buzzert.kordophone.backend.model.Conversation
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.LocalTime
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.Date
|
||||
@@ -54,17 +59,31 @@ fun ConversationListScreen(
|
||||
conversations = conversations,
|
||||
onConversationSelected = onConversationSelected,
|
||||
onSettingsInvoked = onSettingsInvoked,
|
||||
onRefresh = suspend { viewModel.refresh() }
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
fun ConversationListView(
|
||||
conversations: List<Conversation>,
|
||||
onConversationSelected: (conversationID: String) -> Unit,
|
||||
onSettingsInvoked: () -> Unit,
|
||||
onRefresh: suspend () -> Unit,
|
||||
) {
|
||||
val listState = rememberLazyListState()
|
||||
|
||||
val refreshScope = rememberCoroutineScope()
|
||||
var refreshing by remember { mutableStateOf(false) }
|
||||
|
||||
fun refresh() = refreshScope.launch {
|
||||
refreshing = true
|
||||
onRefresh()
|
||||
refreshing = false
|
||||
}
|
||||
|
||||
val refreshState = rememberPullRefreshState(refreshing = refreshing, onRefresh = ::refresh)
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(title = { Text("Conversations") }, actions = {
|
||||
@@ -74,17 +93,30 @@ fun ConversationListView(
|
||||
})
|
||||
}
|
||||
) {
|
||||
LazyColumn(state = listState, modifier = Modifier.padding(it)) {
|
||||
items(conversations) { conversation ->
|
||||
ConversationListItem(
|
||||
name = conversation.formattedDisplayName(),
|
||||
id = conversation.guid,
|
||||
isUnread = conversation.unreadCount > 0,
|
||||
lastMessagePreview = conversation.lastMessagePreview ?: "",
|
||||
date = conversation.date,
|
||||
onClick = { onConversationSelected(conversation.guid) }
|
||||
)
|
||||
Box(Modifier.pullRefresh(refreshState)) {
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
modifier = Modifier
|
||||
.padding(it)
|
||||
.fillMaxSize()
|
||||
) {
|
||||
items(conversations) { conversation ->
|
||||
ConversationListItem(
|
||||
name = conversation.formattedDisplayName(),
|
||||
id = conversation.guid,
|
||||
isUnread = conversation.unreadCount > 0,
|
||||
lastMessagePreview = conversation.lastMessagePreview ?: "",
|
||||
date = conversation.date,
|
||||
onClick = { onConversationSelected(conversation.guid) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
PullRefreshIndicator(
|
||||
refreshing = refreshing,
|
||||
state = refreshState,
|
||||
modifier = Modifier.align(Alignment.TopCenter),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,21 @@
|
||||
package net.buzzert.kordophonedroid.ui.conversationlist
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.buzzert.kordophone.backend.model.Conversation
|
||||
import net.buzzert.kordophone.backend.server.Authentication
|
||||
import net.buzzert.kordophone.backend.server.ChatRepository
|
||||
import net.buzzert.kordophone.backend.server.REPO_LOG
|
||||
import net.buzzert.kordophone.backend.server.RetrofitAPIClient
|
||||
import net.buzzert.kordophonedroid.ui.shared.ServerConfigRepository
|
||||
import java.net.URL
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
const val CL_VM_LOG: String = "ConversationListViewModel"
|
||||
|
||||
@@ -69,4 +65,8 @@ class ConversationListViewModel @Inject constructor(
|
||||
chatRepository.beginWatchingForUpdates(this)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun refresh() {
|
||||
chatRepository.synchronize()
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="true">192.168.1.111</domain>
|
||||
<domain includeSubdomains="true">192.168.1.123</domain>
|
||||
<domain includeSubdomains="true">tesseract.localdomain</domain>
|
||||
<domain includeSubdomains="true">buzzert.kordophone.nor</domain>
|
||||
</domain-config>
|
||||
|
||||
Reference in New Issue
Block a user