Private
Public Access
1
0

ConversationListScreen: Implements pull-to-refresh

This commit is contained in:
2024-03-18 22:48:02 -07:00
parent 3f670671e9
commit c56776842a
3 changed files with 50 additions and 18 deletions

View File

@@ -9,11 +9,16 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Info
import androidx.compose.material.icons.rounded.Settings 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.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue 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.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
@@ -25,10 +30,10 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import kotlinx.coroutines.launch
import net.buzzert.kordophone.backend.model.Conversation import net.buzzert.kordophone.backend.model.Conversation
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.LocalTime
import java.time.ZoneId import java.time.ZoneId
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.util.Date import java.util.Date
@@ -54,17 +59,31 @@ fun ConversationListScreen(
conversations = conversations, conversations = conversations,
onConversationSelected = onConversationSelected, onConversationSelected = onConversationSelected,
onSettingsInvoked = onSettingsInvoked, onSettingsInvoked = onSettingsInvoked,
onRefresh = suspend { viewModel.refresh() }
) )
} }
@Composable @Composable
@OptIn(ExperimentalMaterialApi::class)
fun ConversationListView( fun ConversationListView(
conversations: List<Conversation>, conversations: List<Conversation>,
onConversationSelected: (conversationID: String) -> Unit, onConversationSelected: (conversationID: String) -> Unit,
onSettingsInvoked: () -> Unit, onSettingsInvoked: () -> Unit,
onRefresh: suspend () -> Unit,
) { ) {
val listState = rememberLazyListState() 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( Scaffold(
topBar = { topBar = {
TopAppBar(title = { Text("Conversations") }, actions = { TopAppBar(title = { Text("Conversations") }, actions = {
@@ -74,17 +93,30 @@ fun ConversationListView(
}) })
} }
) { ) {
LazyColumn(state = listState, modifier = Modifier.padding(it)) { Box(Modifier.pullRefresh(refreshState)) {
items(conversations) { conversation -> LazyColumn(
ConversationListItem( state = listState,
name = conversation.formattedDisplayName(), modifier = Modifier
id = conversation.guid, .padding(it)
isUnread = conversation.unreadCount > 0, .fillMaxSize()
lastMessagePreview = conversation.lastMessagePreview ?: "", ) {
date = conversation.date, items(conversations) { conversation ->
onClick = { onConversationSelected(conversation.guid) } 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),
)
} }
} }
} }

View File

@@ -1,25 +1,21 @@
package net.buzzert.kordophonedroid.ui.conversationlist package net.buzzert.kordophonedroid.ui.conversationlist
import android.util.Log import android.util.Log
import androidx.compose.runtime.collectAsState
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import net.buzzert.kordophone.backend.model.Conversation import net.buzzert.kordophone.backend.model.Conversation
import net.buzzert.kordophone.backend.server.Authentication import net.buzzert.kordophone.backend.server.Authentication
import net.buzzert.kordophone.backend.server.ChatRepository 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.kordophone.backend.server.RetrofitAPIClient
import net.buzzert.kordophonedroid.ui.shared.ServerConfigRepository import net.buzzert.kordophonedroid.ui.shared.ServerConfigRepository
import java.net.URL import java.net.URL
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
const val CL_VM_LOG: String = "ConversationListViewModel" const val CL_VM_LOG: String = "ConversationListViewModel"
@@ -69,4 +65,8 @@ class ConversationListViewModel @Inject constructor(
chatRepository.beginWatchingForUpdates(this) chatRepository.beginWatchingForUpdates(this)
} }
} }
suspend fun refresh() {
chatRepository.synchronize()
}
} }

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<network-security-config> <network-security-config>
<domain-config cleartextTrafficPermitted="true"> <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">tesseract.localdomain</domain>
<domain includeSubdomains="true">buzzert.kordophone.nor</domain> <domain includeSubdomains="true">buzzert.kordophone.nor</domain>
</domain-config> </domain-config>