Backend: UI: Implements authentication.
This commit is contained in:
@@ -5,8 +5,10 @@ import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import net.buzzert.kordophone.backend.db.CachedChatDatabase
|
||||
import net.buzzert.kordophone.backend.server.Authentication
|
||||
import net.buzzert.kordophone.backend.server.ChatRepository
|
||||
import net.buzzert.kordophone.backend.server.RetrofitAPIClient
|
||||
import net.buzzert.kordophonedroid.ui.shared.ServerConfigRepository
|
||||
import java.net.URL
|
||||
import javax.inject.Singleton
|
||||
|
||||
@@ -15,9 +17,21 @@ import javax.inject.Singleton
|
||||
object AppModule {
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideChatRepository(): ChatRepository {
|
||||
val host = "http://192.168.1.123:5738"
|
||||
val client = RetrofitAPIClient(URL(host))
|
||||
fun provideChatRepository(configRepository: ServerConfigRepository): ChatRepository {
|
||||
val serverConfig = configRepository.serverConfig.value
|
||||
val authentication = serverConfig.authentication?.let {
|
||||
Authentication(it.username, it.password)
|
||||
}
|
||||
|
||||
// TODO: This is really bad error handling...
|
||||
val baseURL: URL = try { URL(serverConfig.serverName) }
|
||||
catch (e: java.net.MalformedURLException) { URL("http://localhost") }
|
||||
|
||||
val client = RetrofitAPIClient(
|
||||
baseURL = baseURL,
|
||||
authentication = authentication ?: Authentication("", "")
|
||||
)
|
||||
|
||||
val database = CachedChatDatabase.liveDatabase()
|
||||
return ChatRepository(client, database)
|
||||
}
|
||||
|
||||
@@ -128,7 +128,9 @@ fun ConversationListItem(
|
||||
) {
|
||||
Text(
|
||||
name,
|
||||
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
|
||||
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold),
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
)
|
||||
|
||||
Spacer(Modifier.weight(1f))
|
||||
@@ -140,7 +142,8 @@ fun ConversationListItem(
|
||||
.toLocalDateTime()
|
||||
),
|
||||
modifier = Modifier.align(Alignment.CenterVertically),
|
||||
color = MaterialTheme.colors.onBackground.copy(alpha = 0.4f)
|
||||
color = MaterialTheme.colors.onBackground.copy(alpha = 0.4f),
|
||||
maxLines = 1,
|
||||
)
|
||||
|
||||
Spacer(Modifier.width(horizontalPadding))
|
||||
@@ -172,7 +175,7 @@ fun UnreadIndicator(size: Dp, modifier: Modifier = Modifier) {
|
||||
@Composable
|
||||
fun ConversationListItemPreview() {
|
||||
Column(modifier = Modifier.background(MaterialTheme.colors.background)) {
|
||||
ConversationListItem(name = "James Magahern", id = "asdf", lastMessagePreview = "This is a test", date = Date(), isUnread = true) {}
|
||||
ConversationListItem(name = "James MagahernMagahernMagahernMagahernMagahernMagahernMagahern", id = "asdf", lastMessagePreview = "This is a test", date = Date(), isUnread = true) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,12 @@ 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
|
||||
|
||||
@@ -33,23 +36,31 @@ class ConversationListViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
init {
|
||||
// TODO: Is this the best place to put these?
|
||||
// TODO: Need error handling (exceptions thrown below)
|
||||
|
||||
// Perform initial sync
|
||||
viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
chatRepository.synchronize()
|
||||
}
|
||||
}
|
||||
|
||||
// Watch for config changes
|
||||
viewModelScope.launch {
|
||||
serverConfigRepository.serverConfig.collect {
|
||||
serverConfigRepository.serverConfig.collect { config ->
|
||||
Log.d(CL_VM_LOG, "Got settings change.")
|
||||
|
||||
// TODO: Respond to this change.
|
||||
// Should probably just forward this directly to ChatRepository.
|
||||
// Check settings
|
||||
try {
|
||||
val baseURL = URL(config.serverName)
|
||||
val authentication = config.authentication?.let { serverAuth ->
|
||||
Authentication(serverAuth.username, serverAuth.password)
|
||||
} ?: throw Error("No authentication data.")
|
||||
|
||||
// Make new APIClient
|
||||
val apiClient = RetrofitAPIClient(baseURL, authentication)
|
||||
chatRepository.updateAPIClient(apiClient)
|
||||
} catch (e: Error) {
|
||||
Log.e(CL_VM_LOG, "Error re-creating API client for settings change: $e")
|
||||
} catch (e: java.net.MalformedURLException) {
|
||||
Log.e(CL_VM_LOG, "Malformed server URL")
|
||||
}
|
||||
|
||||
// Perform db synchronization
|
||||
withContext(Dispatchers.IO) {
|
||||
chatRepository.synchronize()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ class MessageListViewModel @Inject constructor(
|
||||
private val pendingMessages: MutableStateFlow<List<OutgoingMessage>> = MutableStateFlow(listOf())
|
||||
|
||||
init {
|
||||
// TODO: Need to handle settings changes here!!
|
||||
|
||||
viewModelScope.launch {
|
||||
// Remove pending message after message is delivered.
|
||||
// By now, the repository should've committed this to the store.
|
||||
|
||||
@@ -11,6 +11,7 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.lightColors
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
|
||||
private val DarkColorPalette = darkColors(
|
||||
primary = Purple200,
|
||||
@@ -56,7 +57,13 @@ fun KordophoneTheme(
|
||||
@Composable
|
||||
fun KordophoneTopAppBar(title: String, backAction: () -> Unit) {
|
||||
TopAppBar(
|
||||
title = { Text(title) },
|
||||
title = {
|
||||
Text(
|
||||
text = title,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
IconButton(onClick = backAction) {
|
||||
Icon(Icons.Filled.ArrowBack, null)
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="true">192.168.1.123</domain>
|
||||
<domain includeSubdomains="true">tesseract.localdomain</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
Reference in New Issue
Block a user