properly reverse items

This commit is contained in:
2026-08-08 07:49:51 +03:00
parent 1173a0f5c8
commit 64ee936aa6
7 changed files with 13 additions and 26 deletions
@@ -1,8 +1,5 @@
-- videobox."saved_movie" definition -- videobox."saved_movie" definition
selectByUserId:
SELECT * FROM "saved_movie" WHERE user_id = ? ORDER BY saved_movie_id;
selectByUserIdAndMovieId: selectByUserIdAndMovieId:
SELECT * FROM "saved_movie" WHERE user_id = ? AND movie_id = ?; SELECT * FROM "saved_movie" WHERE user_id = ? AND movie_id = ?;
@@ -22,4 +19,4 @@ SELECT
FROM saved_movie AS sm FROM saved_movie AS sm
JOIN movie AS m ON sm.movie_id = m.movie_id JOIN movie AS m ON sm.movie_id = m.movie_id
WHERE sm.user_id = ? WHERE sm.user_id = ?
ORDER BY sm.saved_movie_id DESC; ORDER BY sm.saved_movie_id ASC;
@@ -1,7 +1,7 @@
package ru.shadowsparky.vbox.shared.presentation package ru.shadowsparky.vbox.shared.presentation
import androiddev.apps.vbox.client.shared.generated.resources.Res import androiddev.apps.vbox.client.shared.generated.resources.Res
import androiddev.apps.vbox.client.shared.generated.resources.chat_title import androiddev.apps.vbox.client.shared.generated.resources.chat_title_app_bar
import androiddev.apps.vbox.client.shared.generated.resources.home import androiddev.apps.vbox.client.shared.generated.resources.home
import androiddev.apps.vbox.client.shared.generated.resources.recommendations import androiddev.apps.vbox.client.shared.generated.resources.recommendations
import androiddev.apps.vbox.client.shared.generated.resources.saved_movies import androiddev.apps.vbox.client.shared.generated.resources.saved_movies
@@ -35,7 +35,7 @@ fun createNavigationList(): List<NavigationEntry<Route>> {
), ),
NavigationEntry( NavigationEntry(
Route.Chat(), Route.Chat(),
stringResource(Res.string.chat_title), stringResource(Res.string.chat_title_app_bar),
painterResource(Res.drawable.svingpt) painterResource(Res.drawable.svingpt)
), ),
NavigationEntry( NavigationEntry(
@@ -77,7 +77,7 @@ fun VideoScreen(component: VideoScreenComponent) {
items, items,
onRefresh = { component.load() }, onRefresh = { component.load() },
onShowOverview = { component.showOverview(it) }, onShowOverview = { component.showOverview(it) },
emptyResource = Res.string.not_found, emptyResource = Res.string.not_found
) )
}, },
appBar = { appBar = {
@@ -125,7 +125,7 @@ fun VideoScreenContent(
AnimatedContent( AnimatedContent(
items, items,
content = { content = {
VideosInfo(items = items, paddingValues, emptyResource) { VideosInfo(items, paddingValues, emptyResource) {
onShowOverview(it.id) onShowOverview(it.id)
} }
} }
@@ -136,7 +136,7 @@ fun VideoScreenContent(
} }
@Composable @Composable
fun VideosInfo( private fun VideosInfo(
items: List<VideoItem>, items: List<VideoItem>,
paddingValues: PaddingValues, paddingValues: PaddingValues,
emptyResource: StringResource, emptyResource: StringResource,
@@ -180,7 +180,7 @@ fun VideosInfo(
} }
@Composable @Composable
fun Poster( private fun Poster(
imageUrl: String, imageUrl: String,
label: String, label: String,
onClick: () -> Unit, onClick: () -> Unit,
@@ -255,7 +255,7 @@ fun Poster(
} }
@Composable @Composable
fun VideosNotFound(emptyResource: StringResource) { private fun VideosNotFound(emptyResource: StringResource) {
Box( Box(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
@@ -8,7 +8,6 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import org.koin.core.annotation.Factory import org.koin.core.annotation.Factory
import org.koin.core.annotation.Named import org.koin.core.annotation.Named
import ru.shadowsparky.ui.nav.RootComponent
import ru.shadowsparky.ui.nav.ComponentFactory import ru.shadowsparky.ui.nav.ComponentFactory
import ru.shadowsparky.ui.nav.RouteNavigator import ru.shadowsparky.ui.nav.RouteNavigator
import ru.shadowsparky.vbox.shared.domain.SavedMovieRepository import ru.shadowsparky.vbox.shared.domain.SavedMovieRepository
@@ -50,7 +49,7 @@ class SavedMovieComponent(
} else { } else {
movies.filter { it.id in ids } movies.filter { it.id in ids }
} }
} }.map { it.reversed() }
fun filterByTag(tagName: String?) { fun filterByTag(tagName: String?) {
filterTagFlow.tryEmit(tagName) filterTagFlow.tryEmit(tagName)
@@ -33,7 +33,6 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextField import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldColors import androidx.compose.material3.TextFieldColors
import androidx.compose.material3.TextFieldDefaults import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberSearchBarState import androidx.compose.material3.rememberSearchBarState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@@ -1,10 +1,10 @@
package ru.shadowsparky.vbox.shared.presentation.search package ru.shadowsparky.vbox.shared.presentation.search
import com.arkivanov.decompose.ComponentContext import com.arkivanov.decompose.ComponentContext
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.core.annotation.Factory import org.koin.core.annotation.Factory
import org.koin.core.annotation.Named import org.koin.core.annotation.Named
import ru.shadowsparky.ui.nav.RootComponent
import ru.shadowsparky.ui.nav.ComponentFactory import ru.shadowsparky.ui.nav.ComponentFactory
import ru.shadowsparky.ui.nav.RouteNavigator import ru.shadowsparky.ui.nav.RouteNavigator
import ru.shadowsparky.vbox.shared.domain.SearchRepository import ru.shadowsparky.vbox.shared.domain.SearchRepository
@@ -19,7 +19,7 @@ class SearchScreenComponent(
val doBack: () -> Unit, val doBack: () -> Unit,
private val searchRepository: SearchRepository, private val searchRepository: SearchRepository,
) : ComponentContext by context { ) : ComponentContext by context {
val info = searchRepository.search("") val info = searchRepository.search("").map { it.reversed() }
private val componentScope = createComponentScope() private val componentScope = createComponentScope()
fun done(request: String) { fun done(request: String) {
@@ -18,17 +18,14 @@ import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
@@ -144,7 +141,7 @@ private fun ChatContent(
LaunchedEffect(state.messages.size) { LaunchedEffect(state.messages.size) {
if (state.messages.isNotEmpty()) { if (state.messages.isNotEmpty()) {
listState.animateScrollToItem(state.messages.lastIndex) listState.animateScrollToItem(0)
} }
} }
@@ -218,7 +215,6 @@ private fun MessageBubble(
onParseMessage: (String) -> List<TextToken>, onParseMessage: (String) -> List<TextToken>,
onClickLink: (String) -> Unit onClickLink: (String) -> Unit
) { ) {
val scrollState = rememberScrollState()
val isUser = message.role == ChatRoles.USER val isUser = message.role == ChatRoles.USER
val alignment = if (isUser) Alignment.CenterEnd else Alignment.CenterStart val alignment = if (isUser) Alignment.CenterEnd else Alignment.CenterStart
val containerColor = if (isUser) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceVariant val containerColor = if (isUser) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.surfaceVariant
@@ -254,11 +250,7 @@ private fun MessageBubble(
} }
} }
Box( Box(
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth().focusable(),
.heightIn(max = 400.dp)
.focusable()
.verticalScroll(scrollState)
,
contentAlignment = alignment contentAlignment = alignment
) { ) {
Card( Card(