mirror of
https://github.com/openflocon/Flocon.git
synced 2026-05-10 02:06:40 +00:00
feat: [DATABASE] display previous queries (#333)
Co-authored-by: Florent Champigny <florent@bere.al>
This commit is contained in:
parent
0a6c15099e
commit
c38e95d8b0
5 changed files with 81 additions and 17 deletions
|
|
@ -7,6 +7,7 @@ import androidx.lifecycle.viewModelScope
|
|||
import io.github.openflocon.domain.common.DispatcherProvider
|
||||
import io.github.openflocon.domain.common.combines
|
||||
import io.github.openflocon.domain.database.usecase.ExecuteDatabaseQueryUseCase
|
||||
import io.github.openflocon.domain.database.usecase.ObserveLastSuccessQueriesUseCase
|
||||
import io.github.openflocon.domain.database.usecase.favorite.GetFavoriteQueryByIdDatabaseUseCase
|
||||
import io.github.openflocon.domain.database.usecase.favorite.SaveQueryAsFavoriteDatabaseUseCase
|
||||
import io.github.openflocon.domain.feedback.FeedbackDisplayer
|
||||
|
|
@ -14,7 +15,6 @@ import io.github.openflocon.flocondesktop.features.database.mapper.toUi
|
|||
import io.github.openflocon.flocondesktop.features.database.model.DatabaseScreenState
|
||||
import io.github.openflocon.flocondesktop.features.database.model.DatabaseTabAction
|
||||
import io.github.openflocon.flocondesktop.features.database.model.QueryResultUiModel
|
||||
import io.github.openflocon.flocondesktop.features.network.list.model.NetworkAction
|
||||
import io.github.openflocon.library.designsystem.common.copyToClipboard
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
|
|
@ -38,6 +38,7 @@ class DatabaseTabViewModel(
|
|||
private val getFavoriteQueryUseCase: GetFavoriteQueryByIdDatabaseUseCase,
|
||||
private val dispatcherProvider: DispatcherProvider,
|
||||
private val feedbackDisplayer: FeedbackDisplayer,
|
||||
private val observeLastSuccessQueriesUseCase: ObserveLastSuccessQueriesUseCase,
|
||||
) : ViewModel() {
|
||||
|
||||
@Immutable
|
||||
|
|
@ -49,6 +50,15 @@ class DatabaseTabViewModel(
|
|||
|
||||
var query = mutableStateOf("")
|
||||
|
||||
val lastQueries = observeLastSuccessQueriesUseCase(params.databaseId)
|
||||
.map { it.filterNot { it.isBlank() } }
|
||||
.flowOn(dispatcherProvider.data)
|
||||
.stateIn(
|
||||
viewModelScope,
|
||||
started = SharingStarted.WhileSubscribed(5_000),
|
||||
emptyList()
|
||||
)
|
||||
|
||||
private val autoUpdateJob = AtomicReference<Job?>(null)
|
||||
|
||||
data class AutoUpdate(
|
||||
|
|
@ -119,12 +129,21 @@ class DatabaseTabViewModel(
|
|||
viewModelScope.launch(dispatcherProvider.viewModel) {
|
||||
when (action) {
|
||||
is DatabaseTabAction.ClearQuery -> clearQuery()
|
||||
is DatabaseTabAction.ExecuteQuery -> executeQuery(query = query.value, editAutoUpdate = true)
|
||||
is DatabaseTabAction.ExecuteQuery -> {
|
||||
query.value = action.query
|
||||
updateQuery(action.query)
|
||||
executeQuery(
|
||||
query = action.query,
|
||||
editAutoUpdate = true
|
||||
)
|
||||
}
|
||||
|
||||
is DatabaseTabAction.UpdateAutoUpdate -> updateAutoUpdate(action.value)
|
||||
DatabaseTabAction.Copy -> {
|
||||
copyToClipboard(query.value)
|
||||
feedbackDisplayer.displayMessage("copied")
|
||||
}
|
||||
|
||||
DatabaseTabAction.Import -> {
|
||||
// TODO
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,12 +9,15 @@ import androidx.compose.foundation.layout.aspectRatio
|
|||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.CopyAll
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.StarBorder
|
||||
import androidx.compose.material.icons.outlined.History
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.VerticalDivider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
|
|
@ -27,14 +30,19 @@ import androidx.compose.ui.draw.clip
|
|||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import io.github.openflocon.flocondesktop.features.database.model.DatabaseTabAction
|
||||
import io.github.openflocon.library.designsystem.FloconTheme
|
||||
import io.github.openflocon.library.designsystem.components.FloconExposedDropdownMenu
|
||||
import io.github.openflocon.library.designsystem.components.FloconExposedDropdownMenuBox
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
internal fun DatabaseQueryToolbarView(
|
||||
favoritesTitles: Set<String>,
|
||||
onAction: (action: DatabaseTabAction) -> Unit,
|
||||
isQueryEmpty: Boolean,
|
||||
lastQueries: List<String>,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var showFavoriteDialog by remember { mutableStateOf(false) }
|
||||
|
|
@ -62,6 +70,7 @@ internal fun DatabaseQueryToolbarView(
|
|||
)
|
||||
}
|
||||
VerticalDivider(modifier = Modifier.padding(vertical = 6.dp, horizontal = 2.dp))
|
||||
|
||||
Box(
|
||||
modifier = Modifier.clip(RoundedCornerShape(2.dp))
|
||||
.clickable(enabled = isQueryEmpty.not()) {
|
||||
|
|
@ -79,19 +88,47 @@ internal fun DatabaseQueryToolbarView(
|
|||
colorFilter = ColorFilter.tint(FloconTheme.colorPalette.onPrimary)
|
||||
)
|
||||
}
|
||||
VerticalDivider(modifier = Modifier.padding(vertical = 6.dp, horizontal = 2.dp))
|
||||
Box(
|
||||
modifier = Modifier.clip(RoundedCornerShape(2.dp)).clickable {
|
||||
|
||||
}.aspectRatio(1f, true),
|
||||
contentAlignment = Alignment.Center
|
||||
VerticalDivider(modifier = Modifier.padding(vertical = 6.dp, horizontal = 2.dp))
|
||||
|
||||
var isHistoryExpanded by remember { mutableStateOf(false) }
|
||||
val displayOldQueries = isHistoryExpanded && lastQueries.isNotEmpty()
|
||||
|
||||
FloconExposedDropdownMenuBox(
|
||||
expanded = displayOldQueries,
|
||||
onExpandedChange = { isHistoryExpanded = false },
|
||||
) {
|
||||
Image(
|
||||
Icons.Outlined.History,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(20.dp),
|
||||
colorFilter = ColorFilter.tint(FloconTheme.colorPalette.onPrimary)
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.clip(RoundedCornerShape(2.dp))
|
||||
.clickable(enabled = lastQueries.isNotEmpty()) {
|
||||
isHistoryExpanded = true
|
||||
}.aspectRatio(1f, true),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Image(
|
||||
Icons.Outlined.History,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(20.dp),
|
||||
colorFilter = ColorFilter.tint(FloconTheme.colorPalette.onPrimary)
|
||||
)
|
||||
}
|
||||
|
||||
FloconExposedDropdownMenu(
|
||||
expanded = displayOldQueries,
|
||||
onDismissRequest = { isHistoryExpanded = false },
|
||||
modifier = Modifier.width(300.dp)
|
||||
) {
|
||||
lastQueries.fastForEach { query ->
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 12.dp, vertical = 8.dp).clickable {
|
||||
onAction(DatabaseTabAction.ExecuteQuery(query))
|
||||
isHistoryExpanded = false
|
||||
},
|
||||
text = query,
|
||||
style = FloconTheme.typography.bodySmall,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* for another MR
|
||||
|
|
@ -138,4 +175,4 @@ internal fun DatabaseQueryToolbarView(
|
|||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ fun DatabaseQueryView(
|
|||
query: String,
|
||||
autoUpdate: Boolean,
|
||||
favoritesTitles: Set<String>,
|
||||
lastQueries: List<String>,
|
||||
updateQuery: (query: String) -> Unit,
|
||||
onAction: (action: DatabaseTabAction) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -54,6 +55,7 @@ fun DatabaseQueryView(
|
|||
DatabaseQueryToolbarView(
|
||||
favoritesTitles = favoritesTitles,
|
||||
onAction = onAction,
|
||||
lastQueries = lastQueries,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
isQueryEmpty = query.isBlank(),
|
||||
)
|
||||
|
|
@ -148,7 +150,8 @@ private fun DatabaseQueryViewPreview() {
|
|||
updateQuery = {},
|
||||
autoUpdate = true,
|
||||
onAction = {},
|
||||
favoritesTitles = emptySet()
|
||||
favoritesTitles = emptySet(),
|
||||
lastQueries = emptyList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
|
|
@ -44,12 +43,15 @@ fun DatabaseTabView(
|
|||
|
||||
val state: DatabaseScreenState by viewModel.state.collectAsStateWithLifecycle()
|
||||
val autoUpdate by viewModel.isAutoUpdateEnabled.collectAsStateWithLifecycle()
|
||||
val lastQueries by viewModel.lastQueries.collectAsStateWithLifecycle()
|
||||
|
||||
DatabaseTabViewContent(
|
||||
query = viewModel.query.value,
|
||||
autoUpdate = autoUpdate,
|
||||
updateQuery = viewModel::updateQuery,
|
||||
onAction = viewModel::onAction,
|
||||
state = state,
|
||||
lastQueries = lastQueries,
|
||||
favoritesTitles = favoritesTitles,
|
||||
)
|
||||
}
|
||||
|
|
@ -62,6 +64,7 @@ private fun DatabaseTabViewContent(
|
|||
updateQuery: (String) -> Unit,
|
||||
onAction: (action: DatabaseTabAction) -> Unit,
|
||||
state: DatabaseScreenState,
|
||||
lastQueries: List<String>,
|
||||
) {
|
||||
Column(
|
||||
Modifier.fillMaxSize(),
|
||||
|
|
@ -76,6 +79,7 @@ private fun DatabaseTabViewContent(
|
|||
autoUpdate = autoUpdate,
|
||||
onAction = onAction,
|
||||
favoritesTitles = favoritesTitles,
|
||||
lastQueries = lastQueries,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package io.github.openflocon.domain.database.usecase
|
|||
|
||||
import io.github.openflocon.domain.device.usecase.ObserveCurrentDeviceIdAndPackageNameUseCase
|
||||
import io.github.openflocon.domain.database.repository.DatabaseRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
||||
|
|
@ -11,7 +12,7 @@ class ObserveLastSuccessQueriesUseCase(
|
|||
) {
|
||||
operator fun invoke(
|
||||
databaseId: String,
|
||||
) = observeCurrentDeviceIdAndPackageNameUseCase().flatMapLatest { model ->
|
||||
): Flow<List<String>> = observeCurrentDeviceIdAndPackageNameUseCase().flatMapLatest { model ->
|
||||
if (model == null) {
|
||||
flowOf(emptyList())
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue