diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/DirectMessageDetailScreen.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/DirectMessageDetailScreen.kt new file mode 100644 index 00000000..209ee5c9 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/DirectMessageDetailScreen.kt @@ -0,0 +1,95 @@ +package ac.cord.auxiliary.compose.ui.composable + +import ac.cord.auxiliary.compose.repository.NostrRepository +import ac.cord.auxiliary.compose.ui.composable.widgets.LoadingDataIndicator +import ac.cord.auxiliary.compose.ui.theme.AuxTheme +import ac.cord.auxiliary.compose.ui.view.model.DirectMessageDetailViewModel +import ac.cord.auxiliary.compose.ui.view.model.UnqueuedProfileSynchronizationViewModel +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel + +@OptIn(ExperimentalMaterial3ExpressiveApi::class) +@Composable +fun DirectMessageDetailScreen( + nostrRepository: NostrRepository +) { + val directMessageDetailViewModel: DirectMessageDetailViewModel = viewModel( + factory = DirectMessageDetailViewModel.factory( + nostrRepository = nostrRepository + ) + ) + + Scaffold { innerPadding -> + Column( + modifier = Modifier.padding(innerPadding) + ) { + + Column( + modifier = Modifier.fillMaxWidth().padding( + 10.dp + ), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + + Spacer( + modifier = Modifier.weight(1f) + ) + Text( + text = "Direct Message Detail", + style = MaterialTheme.typography.bodyLarge, + textAlign = TextAlign.Center + ) + + Text( + text = "Direct message functionality will be here.", + style = MaterialTheme.typography.bodySmall, + textAlign = TextAlign.Center + ) + + LoadingDataIndicator( + fillScreen = false + ) + + Spacer( + modifier = Modifier.weight(2f) + ) + } + } + } + + LaunchedEffect(true) { + directMessageDetailViewModel.queueSynchronization() + } +} + +@Preview +@Composable +private fun UnqueuedProfileSynchronizationScreenPreview() { + AuxTheme { + Surface( + modifier = Modifier.fillMaxSize() + ) { + DirectMessageDetailScreen( + nostrRepository = NostrRepository.NO_OP_NOSTR_REPOSITORY + ) + } + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/HomeScreen.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/HomeScreen.kt index 085b7c00..6e5265cb 100644 --- a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/HomeScreen.kt +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/HomeScreen.kt @@ -56,6 +56,7 @@ import kotlinx.coroutines.launch fun HomeScreen( initialHomeScreenUIState: HomeScreenUIState = HomeScreenUIState.Loading, onNavigateToEvent: (Route) -> Unit, + onNavigateToDirectMessageDetail: () -> Unit, onNavigateToWriteNewNote: () -> Unit, onNavigateToSearch: () -> Unit, nostrRepository: NostrRepository, @@ -225,7 +226,9 @@ fun HomeScreen( key(directMessageListViewModel.directMessageListUIState) { directMessageListViewModel.RenderFeed( - onNavigateToEvent = onNavigateToEvent + onNavigateToDirectMessageDetail = { + onNavigateToDirectMessageDetail.invoke() + } ) } @@ -282,6 +285,7 @@ It has survived not only five centuries, but also the leap into electronic types onNavigateToEvent = {}, onNavigateToWriteNewNote = {}, onNavigateToSearch = {}, + onNavigateToDirectMessageDetail = {}, nostrRepository = NostrRepository.NO_OP_NOSTR_REPOSITORY ) } diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/navigation/AuxNavHost.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/navigation/AuxNavHost.kt index dbbb6c38..faf86729 100644 --- a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/navigation/AuxNavHost.kt +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/navigation/AuxNavHost.kt @@ -5,6 +5,7 @@ import ac.cord.auxiliary.compose.database.repository.DatabaseNostrRepository import ac.cord.auxiliary.compose.database.repository.DatabaseSearchRepository import ac.cord.auxiliary.compose.managers.DatabaseManager import ac.cord.auxiliary.compose.ui.composable.CreateProfileScreen +import ac.cord.auxiliary.compose.ui.composable.DirectMessageDetailScreen import ac.cord.auxiliary.compose.ui.composable.HomeScreen import ac.cord.auxiliary.compose.ui.composable.ImplementationPendingScreen import ac.cord.auxiliary.compose.ui.composable.LandingScreen @@ -23,6 +24,7 @@ import ac.cord.auxiliary.compose.ui.composable.UnsyncedProfileScreen import ac.cord.auxiliary.compose.ui.composable.WriteNewNoteScreen import ac.cord.auxiliary.compose.ui.composable.navigation.routes.BlankRoute import ac.cord.auxiliary.compose.ui.composable.navigation.routes.CreateProfileRoute +import ac.cord.auxiliary.compose.ui.composable.navigation.routes.DirectMessageDetailRoute import ac.cord.auxiliary.compose.ui.composable.navigation.routes.FeedRoute import ac.cord.auxiliary.compose.ui.composable.navigation.routes.ImplementationPendingRoute import ac.cord.auxiliary.compose.ui.composable.navigation.routes.LandingRoute @@ -332,6 +334,13 @@ fun AuxNavHost( route = SearchRoute ) }, + onNavigateToDirectMessageDetail = { + navController.navigate( + route = DirectMessageDetailRoute( + directMessageIdentifier = "" + ) + ) + }, nostrRepository = databaseNostrRepository ) } @@ -343,6 +352,11 @@ fun AuxNavHost( } } + composable { + DirectMessageDetailScreen( + nostrRepository = databaseNostrRepository + ) + } composable { SearchScreen( initialSearchUIState = SearchUIState.Prompt, diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/navigation/routes/DirectMessageDetailRoute.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/navigation/routes/DirectMessageDetailRoute.kt new file mode 100755 index 00000000..eecbbedb --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/composable/navigation/routes/DirectMessageDetailRoute.kt @@ -0,0 +1,9 @@ +package ac.cord.auxiliary.compose.ui.composable.navigation.routes + +import kotlinx.serialization.Serializable + +@Serializable +data class DirectMessageDetailRoute( + val directMessageIdentifier: String, +): Route() { +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/DirectMessageDetailViewModel.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/DirectMessageDetailViewModel.kt new file mode 100644 index 00000000..9248ceba --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/DirectMessageDetailViewModel.kt @@ -0,0 +1,52 @@ +package ac.cord.auxiliary.compose.ui.view.model + +import ac.cord.auxiliary.compose.database.model.SynchronizeNostrEventRequest +import ac.cord.auxiliary.compose.database.model.types.SynchronizationFilter +import ac.cord.auxiliary.compose.nostr.Relays +import ac.cord.auxiliary.compose.repository.NostrRepository +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewmodel.initializer +import androidx.lifecycle.viewmodel.viewModelFactory +import androidx.lifecycle.viewModelScope +import co.touchlab.kermit.Logger +import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent +import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip17Dm.settings.ChatMessageRelayListEvent +import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListEvent +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent +import com.vitorpamplona.quartz.nip51Lists.relayLists.RelayFeedsListEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +class DirectMessageDetailViewModel( + val nostrRepository: NostrRepository +): ViewModel() { + companion object { + private const val TAG = "DirectMessageDetailViewModel" + + fun factory( + nostrRepository: NostrRepository + ): ViewModelProvider.Factory = viewModelFactory { + initializer { + DirectMessageDetailViewModel( + nostrRepository = nostrRepository + ) + } + } + } + + private val logger = Logger.withTag(TAG) + + val isActionPending: MutableState = mutableStateOf(false) + + fun queueSynchronization() { + logger.d { "queueSynchronization" } + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/DirectMessageListViewModel.kt b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/DirectMessageListViewModel.kt index 4232120f..af7137c3 100755 --- a/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/DirectMessageListViewModel.kt +++ b/composeApp/src/commonMain/kotlin/ac/cord/auxiliary/compose/ui/view/model/DirectMessageListViewModel.kt @@ -101,14 +101,13 @@ class DirectMessageListViewModel( @OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable fun RenderFeed( - onNavigateToEvent: (Route) -> Unit + onNavigateToDirectMessageDetail: (String) -> Unit ) { - Column( modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) { - when (val feedListUIState = directMessageListUIState) { + when (val directMessageListUIState = directMessageListUIState) { DirectMessageListUIState.Error -> { Column( modifier = Modifier.fillMaxWidth(), @@ -135,7 +134,7 @@ class DirectMessageListViewModel( Card( modifier = Modifier.fillMaxWidth(), onClick = { - + onNavigateToDirectMessageDetail.invoke("") } ) { Column( @@ -152,7 +151,7 @@ class DirectMessageListViewModel( Card( modifier = Modifier.fillMaxWidth(), onClick = { - + onNavigateToDirectMessageDetail.invoke("") } ) { Column( @@ -169,7 +168,7 @@ class DirectMessageListViewModel( Card( modifier = Modifier.fillMaxWidth(), onClick = { - + onNavigateToDirectMessageDetail.invoke("") } ) { Column( @@ -186,7 +185,7 @@ class DirectMessageListViewModel( Card( modifier = Modifier.fillMaxWidth(), onClick = { - + onNavigateToDirectMessageDetail.invoke("") } ) { Column( @@ -203,7 +202,7 @@ class DirectMessageListViewModel( Card( modifier = Modifier.fillMaxWidth(), onClick = { - + onNavigateToDirectMessageDetail.invoke("") } ) { Column(