refactor settings views

This commit is contained in:
Owen LeJeune
2022-09-03 22:04:51 -04:00
parent dcaa6ed361
commit c5e4069118
10 changed files with 211 additions and 101 deletions

View File

@@ -3,7 +3,6 @@ package com.owenlejeune.tvtime
import android.os.Bundle import android.os.Bundle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.animation.rememberSplineBasedDecay import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Scaffold import androidx.compose.material.Scaffold
@@ -14,8 +13,6 @@ import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
@@ -35,12 +32,14 @@ import com.kieronquinn.monetcompat.app.MonetCompatActivity
import com.owenlejeune.tvtime.extensions.WindowSizeClass import com.owenlejeune.tvtime.extensions.WindowSizeClass
import com.owenlejeune.tvtime.extensions.rememberWindowSizeClass import com.owenlejeune.tvtime.extensions.rememberWindowSizeClass
import com.owenlejeune.tvtime.preferences.AppPreferences import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.ui.components.RoundedTextField
import com.owenlejeune.tvtime.ui.components.SearchFab
import com.owenlejeune.tvtime.ui.navigation.BottomNavItem import com.owenlejeune.tvtime.ui.navigation.BottomNavItem
import com.owenlejeune.tvtime.ui.navigation.MainNavGraph import com.owenlejeune.tvtime.ui.navigation.MainNavGraph
import com.owenlejeune.tvtime.ui.navigation.MainNavItem import com.owenlejeune.tvtime.ui.navigation.MainNavItem
import com.owenlejeune.tvtime.ui.screens.main.* import com.owenlejeune.tvtime.ui.screens.SearchScreen
import com.owenlejeune.tvtime.ui.screens.main.MediaDetailView
import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
import com.owenlejeune.tvtime.ui.screens.main.PersonDetailView
import com.owenlejeune.tvtime.ui.screens.main.SettingsTab
import com.owenlejeune.tvtime.ui.theme.TVTimeTheme import com.owenlejeune.tvtime.ui.theme.TVTimeTheme
import com.owenlejeune.tvtime.utils.KeyboardManager import com.owenlejeune.tvtime.utils.KeyboardManager
import com.owenlejeune.tvtime.utils.SessionManager import com.owenlejeune.tvtime.utils.SessionManager
@@ -52,8 +51,6 @@ import org.koin.java.KoinJavaComponent.get
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
class MainActivity : MonetCompatActivity() { class MainActivity : MonetCompatActivity() {
private val searchableScreens = listOf(BottomNavItem.Movies.route, BottomNavItem.TV.route, BottomNavItem.People.route)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -101,10 +98,8 @@ class MainActivity : MonetCompatActivity() {
TopAppBarDefaults.exitUntilCollapsedScrollBehavior(decayAnimationSpec, topAppBarScrollState) TopAppBarDefaults.exitUntilCollapsedScrollBehavior(decayAnimationSpec, topAppBarScrollState)
} }
val focusRequester = remember { FocusRequester() } val appBarActions = remember { mutableStateOf<@Composable RowScope.() -> Unit>({}) }
val focusSearchBar = rememberSaveable { mutableStateOf(false) } val fab = remember { mutableStateOf<@Composable () -> Unit>({}) }
val appBarActions = remember { mutableStateOf<@Composable RowScope.() -> Unit>( {} ) }
// todo - scroll state not remember when returing from detail screen // todo - scroll state not remember when returing from detail screen
@@ -121,12 +116,7 @@ class MainActivity : MonetCompatActivity() {
} }
}, },
floatingActionButton = { floatingActionButton = {
if (currentRoute in searchableScreens && !preferences.persistentSearch && !focusSearchBar.value) { fab.value()
SearchFab(
focusSearchBar = focusSearchBar,
focusRequester = focusRequester
)
}
}, },
bottomBar = { bottomBar = {
if (windowSize != WindowSizeClass.Expanded) { if (windowSize != WindowSizeClass.Expanded) {
@@ -139,6 +129,7 @@ class MainActivity : MonetCompatActivity() {
windowSize = windowSize, windowSize = windowSize,
appNavController = appNavController, appNavController = appNavController,
navController = navController, navController = navController,
fab = fab,
appBarTitle = appBarTitle, appBarTitle = appBarTitle,
appBarActions = appBarActions, appBarActions = appBarActions,
topBarScrollBehaviour = scrollBehavior, topBarScrollBehaviour = scrollBehavior,
@@ -225,33 +216,12 @@ class MainActivity : MonetCompatActivity() {
} }
} }
@Composable
private fun SearchBar(
textState: MutableState<String>,
placeholder: String
) {
RoundedTextField(
modifier = Modifier
.padding(all = 12.dp)
.height(35.dp),
value = textState.value,
onValueChange = { textState.value = it },
placeHolder = stringResource(id = R.string.search_placeholder, placeholder),
trailingIcon = {
Image(
painter = painterResource(id = R.drawable.ic_search),
contentDescription = stringResource(R.string.search_icon_content_descriptor),
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.primary)
)
}
)
}
@Composable @Composable
private fun MainContent( private fun MainContent(
windowSize: WindowSizeClass, windowSize: WindowSizeClass,
appNavController: NavHostController, appNavController: NavHostController,
navController: NavHostController, navController: NavHostController,
fab: MutableState<@Composable () -> Unit>,
topBarScrollBehaviour: TopAppBarScrollBehavior, topBarScrollBehaviour: TopAppBarScrollBehavior,
appBarTitle: MutableState<String>, appBarTitle: MutableState<String>,
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}), appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
@@ -261,6 +231,7 @@ class MainActivity : MonetCompatActivity() {
DualColumnMainContent( DualColumnMainContent(
appNavController = appNavController, appNavController = appNavController,
navController = navController, navController = navController,
fab = fab,
appBarTitle = appBarTitle, appBarTitle = appBarTitle,
appBarActions = appBarActions, appBarActions = appBarActions,
topBarScrollBehaviour = topBarScrollBehaviour, topBarScrollBehaviour = topBarScrollBehaviour,
@@ -270,6 +241,7 @@ class MainActivity : MonetCompatActivity() {
SingleColumnMainContent( SingleColumnMainContent(
appNavController = appNavController, appNavController = appNavController,
navController = navController, navController = navController,
fab = fab,
appBarTitle = appBarTitle, appBarTitle = appBarTitle,
appBarActions = appBarActions, appBarActions = appBarActions,
mainNavStartRoute = mainNavStartRoute mainNavStartRoute = mainNavStartRoute
@@ -281,6 +253,7 @@ class MainActivity : MonetCompatActivity() {
private fun SingleColumnMainContent( private fun SingleColumnMainContent(
appNavController: NavHostController, appNavController: NavHostController,
navController: NavHostController, navController: NavHostController,
fab: MutableState<@Composable () -> Unit>,
appBarTitle: MutableState<String>, appBarTitle: MutableState<String>,
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}), appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
mainNavStartRoute: String = BottomNavItem.Items[0].route mainNavStartRoute: String = BottomNavItem.Items[0].route
@@ -288,6 +261,7 @@ class MainActivity : MonetCompatActivity() {
MainMediaView( MainMediaView(
appNavController = appNavController, appNavController = appNavController,
navController = navController, navController = navController,
fab = fab,
appBarTitle = appBarTitle, appBarTitle = appBarTitle,
appBarActions = appBarActions, appBarActions = appBarActions,
mainNavStartRoute = mainNavStartRoute mainNavStartRoute = mainNavStartRoute
@@ -298,6 +272,7 @@ class MainActivity : MonetCompatActivity() {
private fun DualColumnMainContent( private fun DualColumnMainContent(
appNavController: NavHostController, appNavController: NavHostController,
navController: NavHostController, navController: NavHostController,
fab: MutableState<@Composable () -> Unit>,
topBarScrollBehaviour: TopAppBarScrollBehavior, topBarScrollBehaviour: TopAppBarScrollBehavior,
appBarTitle: MutableState<String>, appBarTitle: MutableState<String>,
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}), appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
@@ -335,6 +310,7 @@ class MainActivity : MonetCompatActivity() {
MainMediaView( MainMediaView(
appNavController = appNavController, appNavController = appNavController,
navController = navController, navController = navController,
fab = fab,
appBarTitle = appBarTitle, appBarTitle = appBarTitle,
appBarActions = appBarActions, appBarActions = appBarActions,
mainNavStartRoute = mainNavStartRoute mainNavStartRoute = mainNavStartRoute
@@ -347,6 +323,7 @@ class MainActivity : MonetCompatActivity() {
private fun MainMediaView( private fun MainMediaView(
appNavController: NavHostController, appNavController: NavHostController,
navController: NavHostController, navController: NavHostController,
fab: MutableState<@Composable () -> Unit>,
appBarTitle: MutableState<String>, appBarTitle: MutableState<String>,
appBarActions: MutableState<RowScope.() -> Unit> = mutableStateOf({}), appBarActions: MutableState<RowScope.() -> Unit> = mutableStateOf({}),
mainNavStartRoute: String = BottomNavItem.Items[0].route mainNavStartRoute: String = BottomNavItem.Items[0].route
@@ -355,18 +332,15 @@ class MainActivity : MonetCompatActivity() {
val navBackStackEntry by navController.currentBackStackEntryAsState() val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route val currentRoute = navBackStackEntry?.destination?.route
if (currentRoute in searchableScreens) { // if (currentRoute in searchableScreens) {
val textState = remember { mutableStateOf("") } // SearchBar(appBarTitle.value)
SearchBar( // }
textState,
appBarTitle.value
)
}
MainNavGraph( MainNavGraph(
activity = this@MainActivity, activity = this@MainActivity,
appNavController = appNavController, appNavController = appNavController,
navController = navController, navController = navController,
fab = fab,
appBarTitle = appBarTitle, appBarTitle = appBarTitle,
appBarActions = appBarActions, appBarActions = appBarActions,
startDestination = mainNavStartRoute startDestination = mainNavStartRoute
@@ -378,6 +352,7 @@ class MainActivity : MonetCompatActivity() {
const val ID_KEY = "id_key" const val ID_KEY = "id_key"
const val TYPE_KEY = "type_key" const val TYPE_KEY = "type_key"
const val SETTINGS_KEY = "settings_key" const val SETTINGS_KEY = "settings_key"
const val SEARCH_KEY = "search_key"
} }
@Composable @Composable
@@ -428,6 +403,14 @@ class MainActivity : MonetCompatActivity() {
composable(MainNavItem.SettingsView.route) { composable(MainNavItem.SettingsView.route) {
SettingsTab(appNavController = appNavController, activity = this@MainActivity) SettingsTab(appNavController = appNavController, activity = this@MainActivity)
} }
composable(
route = MainNavItem.SearchView.route.plus("/{${NavConstants.SEARCH_KEY}}"),
arguments = listOf(
navArgument(NavConstants.SEARCH_KEY) { type = NavType.IntType }
)
) {
SearchScreen(appNavController = appNavController)
}
} }
} }

View File

@@ -15,7 +15,6 @@ class AppPreferences(context: Context) {
// private val USE_PREFERENCES = "use_android_12_colors" // private val USE_PREFERENCES = "use_android_12_colors"
private val PERSISTENT_SEARCH = "persistent_search" private val PERSISTENT_SEARCH = "persistent_search"
private val HIDE_TITLE = "hide_title"
private val GUEST_SESSION = "guest_session_id" private val GUEST_SESSION = "guest_session_id"
private val AUTHORIZED_SESSION = "authorized_session_id" private val AUTHORIZED_SESSION = "authorized_session_id"
private val AUTHORIZED_SESSION_VALUES = "authorized_session_values" private val AUTHORIZED_SESSION_VALUES = "authorized_session_values"
@@ -33,14 +32,10 @@ class AppPreferences(context: Context) {
private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE) private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE)
/******** Search Preferences ********/ /******** Search Preferences ********/
var persistentSearch: Boolean var showSearchBar: Boolean
get() = preferences.getBoolean(PERSISTENT_SEARCH, true) get() = preferences.getBoolean(PERSISTENT_SEARCH, true)
set(value) { preferences.put(PERSISTENT_SEARCH, value) } set(value) { preferences.put(PERSISTENT_SEARCH, value) }
var hideTitle: Boolean
get() = preferences.getBoolean(HIDE_TITLE, false)
set(value) { preferences.put(HIDE_TITLE, value) }
var useWallpaperColors: Boolean var useWallpaperColors: Boolean
get() = preferences.getBoolean(USE_WALLPAPER_COLORS, true) get() = preferences.getBoolean(USE_WALLPAPER_COLORS, true)
set(value) { preferences.put(USE_WALLPAPER_COLORS, value) } set(value) { preferences.put(USE_WALLPAPER_COLORS, value) }
@@ -91,8 +86,11 @@ class AppPreferences(context: Context) {
get() = preferences.getBoolean(USE_V4_API, true) get() = preferences.getBoolean(USE_V4_API, true)
set(value) { preferences.put(USE_V4_API, value) } set(value) { preferences.put(USE_V4_API, value) }
var showBackdropGallery: Boolean = true var showBackdropGallery: Boolean// = true
get() = preferences.getBoolean(SHOW_BACKDROP_GALLERY, true)
set(value) { preferences.put(SHOW_BACKDROP_GALLERY, value) }
/********* Helpers ********/
private fun SharedPreferences.put(key: String, value: Any?) { private fun SharedPreferences.put(key: String, value: Any?) {
edit().apply { edit().apply {
when (value) { when (value) {

View File

@@ -43,6 +43,7 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextLayoutResult import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
@@ -60,12 +61,16 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.navigation.NavHostController
import coil.compose.AsyncImage import coil.compose.AsyncImage
import coil.compose.rememberAsyncImagePainter import coil.compose.rememberAsyncImagePainter
import com.google.accompanist.flowlayout.FlowRow import com.google.accompanist.flowlayout.FlowRow
import com.kieronquinn.monetcompat.core.MonetCompat import com.kieronquinn.monetcompat.core.MonetCompat
import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.AuthorDetails import com.owenlejeune.tvtime.api.tmdb.api.v3.model.AuthorDetails
import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
import com.owenlejeune.tvtime.ui.theme.RatingSelected import com.owenlejeune.tvtime.ui.theme.RatingSelected
import com.owenlejeune.tvtime.utils.TmdbUtils import com.owenlejeune.tvtime.utils.TmdbUtils
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer
@@ -76,6 +81,7 @@ import kotlinx.coroutines.launch
import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor
import org.intellij.markdown.html.HtmlGenerator import org.intellij.markdown.html.HtmlGenerator
import org.intellij.markdown.parser.MarkdownParser import org.intellij.markdown.parser.MarkdownParser
import org.koin.java.KoinJavaComponent
import kotlin.math.exp import kotlin.math.exp
@Composable @Composable
@@ -199,17 +205,30 @@ fun CustomSwitch(
} }
@Composable @Composable
fun SearchFab( fun SearchView(
focusSearchBar: MutableState<Boolean> = mutableStateOf(false), title: String,
focusRequester: FocusRequester = remember { FocusRequester() } appNavController: NavHostController,
mediaType: MediaViewType,
fab: MutableState<@Composable () -> Unit>,
preferences: AppPreferences = KoinJavaComponent.get(AppPreferences::class.java)
) { ) {
val context = LocalContext.current val route = "${MainNavItem.SearchView.route}/${mediaType.ordinal}"
FloatingActionButton(onClick = { if (preferences.showSearchBar) {
focusSearchBar.value = true SearchBar(
// focusRequester.requestFocus() placeholder = title
// Toast.makeText(context, "Search Clicked!", Toast.LENGTH_SHORT).show() ) {
}) { appNavController.navigate(route)
Icon(Icons.Filled.Search, "") }
} else {
fab.value = @Composable {
FloatingActionButton(
onClick = {
appNavController.navigate(route)
}
) {
Icon(Icons.Filled.Search, stringResource(id = R.string.preference_heading_search))
}
}
} }
} }
@@ -484,7 +503,7 @@ fun RoundedTextField(
) { ) {
Surface( Surface(
modifier = modifier, modifier = modifier,
shape = RoundedCornerShape(50.dp), shape = RoundedCornerShape(25.dp),
color = backgroundColor color = backgroundColor
) { ) {
Row(Modifier.padding(horizontal = 12.dp), Row(Modifier.padding(horizontal = 12.dp),
@@ -1006,7 +1025,27 @@ fun <T> Spinner(
} }
@Composable @Composable
@Preview fun SearchBar(
fun SpinnerPreview() { placeholder: String,
Spinner(list = listOf("T" to "T", "Q" to "Q", "F" to "F"), modifier = Modifier.width(300.dp), preselected = "T" to "T", onSelectionChanged = {}) onClick: () -> Unit
) {
RoundedTextField(
modifier = Modifier
.padding(all = 12.dp)
.height(55.dp)
.clickable(
onClick = onClick
),
value = "",
enabled = false,
onValueChange = { },
placeHolder = stringResource(id = R.string.search_placeholder, placeholder),
leadingIcon = {
Image(
painter = painterResource(id = R.drawable.ic_search),
contentDescription = stringResource(R.string.search_icon_content_descriptor),
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.primary)
)
}
)
} }

View File

@@ -9,5 +9,6 @@ sealed class MainNavItem(val route: String) {
object MainView: MainNavItem("main_route") object MainView: MainNavItem("main_route")
object DetailView: MainNavItem("detail_route") object DetailView: MainNavItem("detail_route")
object SettingsView: MainNavItem("settings_route") object SettingsView: MainNavItem("settings_route")
object SearchView: MainNavItem("search_route")
} }

View File

@@ -24,6 +24,7 @@ fun MainNavGraph(
activity: AppCompatActivity, activity: AppCompatActivity,
appNavController: NavHostController, appNavController: NavHostController,
navController: NavHostController, navController: NavHostController,
fab: MutableState<@Composable () -> Unit>,
appBarTitle: MutableState<String>, appBarTitle: MutableState<String>,
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}), appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
startDestination: String = BottomNavItem.Items[0].route startDestination: String = BottomNavItem.Items[0].route
@@ -31,18 +32,32 @@ fun MainNavGraph(
NavHost(navController = navController, startDestination = startDestination) { NavHost(navController = navController, startDestination = startDestination) {
composable(BottomNavItem.Movies.route) { composable(BottomNavItem.Movies.route) {
appBarActions.value = {} appBarActions.value = {}
MediaTab(appBarTitle = appBarTitle, appNavController = appNavController, mediaType = MediaViewType.MOVIE) MediaTab(
appBarTitle = appBarTitle,
appNavController = appNavController,
mediaType = MediaViewType.MOVIE,
fab = fab
)
} }
composable(BottomNavItem.TV.route) { composable(BottomNavItem.TV.route) {
appBarActions.value = {} appBarActions.value = {}
MediaTab(appBarTitle = appBarTitle, appNavController = appNavController, mediaType = MediaViewType.TV) MediaTab(
appBarTitle = appBarTitle,
appNavController = appNavController,
mediaType = MediaViewType.TV,
fab = fab
)
} }
composable(BottomNavItem.Account.route) { composable(BottomNavItem.Account.route) {
AccountTab(appBarTitle = appBarTitle, appNavController = appNavController, appBarActions = appBarActions) AccountTab(appBarTitle = appBarTitle, appNavController = appNavController, appBarActions = appBarActions)
} }
composable(BottomNavItem.People.route) { composable(BottomNavItem.People.route) {
appBarActions.value = {} appBarActions.value = {}
PeopleTab(appBarTitle = appBarTitle, appNavController = appNavController) PeopleTab(
appBarTitle = appBarTitle,
appNavController = appNavController,
fab = fab
)
} }
composable(BottomNavItem.Favourites.route) { composable(BottomNavItem.Favourites.route) {
appBarActions.value = {} appBarActions.value = {}

View File

@@ -0,0 +1,33 @@
package com.owenlejeune.tvtime.ui.screens
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
@Composable
fun SearchScreen(
appNavController: NavHostController
) {
Column(
modifier = Modifier
.clickable(
onClick = {
appNavController.popBackStack()
}
)
.fillMaxSize()
) {
Spacer(modifier = Modifier.weight(1f))
Text(
modifier = Modifier.align(Alignment.CenterHorizontally),
text = "Search"
)
Spacer(modifier = Modifier.weight(1f))
}
}

View File

@@ -1,6 +1,10 @@
package com.owenlejeune.tvtime.ui.screens.main package com.owenlejeune.tvtime.ui.screens.main
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@@ -16,8 +20,11 @@ import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.HomePageService import com.owenlejeune.tvtime.api.tmdb.api.v3.HomePageService
import com.owenlejeune.tvtime.api.tmdb.api.v3.MoviesService import com.owenlejeune.tvtime.api.tmdb.api.v3.MoviesService
import com.owenlejeune.tvtime.api.tmdb.api.v3.TvService import com.owenlejeune.tvtime.api.tmdb.api.v3.TvService
import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.ui.components.PagingPosterGrid import com.owenlejeune.tvtime.ui.components.PagingPosterGrid
import com.owenlejeune.tvtime.ui.components.PosterGrid import com.owenlejeune.tvtime.ui.components.PosterGrid
import com.owenlejeune.tvtime.ui.components.SearchBar
import com.owenlejeune.tvtime.ui.components.SearchView
import com.owenlejeune.tvtime.ui.navigation.MainNavItem import com.owenlejeune.tvtime.ui.navigation.MainNavItem
import com.owenlejeune.tvtime.ui.navigation.MediaFetchFun import com.owenlejeune.tvtime.ui.navigation.MediaFetchFun
import com.owenlejeune.tvtime.ui.navigation.MediaTabNavItem import com.owenlejeune.tvtime.ui.navigation.MediaTabNavItem
@@ -27,13 +34,15 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.koin.java.KoinJavaComponent.get
@OptIn(ExperimentalPagerApi::class) @OptIn(ExperimentalPagerApi::class)
@Composable @Composable
fun MediaTab( fun MediaTab(
appBarTitle: MutableState<String>, appBarTitle: MutableState<String>,
appNavController: NavHostController, appNavController: NavHostController,
mediaType: MediaViewType mediaType: MediaViewType,
fab: MutableState<@Composable () -> Unit>
) { ) {
appBarTitle.value = when (mediaType) { appBarTitle.value = when (mediaType) {
MediaViewType.MOVIE -> stringResource(id = R.string.nav_movies_title) MediaViewType.MOVIE -> stringResource(id = R.string.nav_movies_title)
@@ -42,6 +51,13 @@ fun MediaTab(
} }
Column { Column {
SearchView(
title = appBarTitle.value,
appNavController = appNavController,
mediaType = mediaType,
fab = fab
)
val tabs = when (mediaType) { val tabs = when (mediaType) {
MediaViewType.MOVIE -> MediaTabNavItem.MovieItems MediaViewType.MOVIE -> MediaTabNavItem.MovieItems
MediaViewType.TV -> MediaTabNavItem.TvItems MediaViewType.TV -> MediaTabNavItem.TvItems
@@ -88,4 +104,32 @@ fun MediaTabs(
HorizontalPager(count = tabs.size, state = pagerState) { page -> HorizontalPager(count = tabs.size, state = pagerState) { page ->
tabs[page].screen(appNavController, mediaViewType, tabs[page]) tabs[page].screen(appNavController, mediaViewType, tabs[page])
} }
} }
//@Composable
//private fun SearchView(
// title: String,
// appNavController: NavHostController,
// mediaType: MediaViewType,
// fab: MutableState<@Composable () -> Unit>,
// preferences: AppPreferences = get(AppPreferences::class.java)
//) {
// val route = "${MainNavItem.SearchView.route}/${mediaType.ordinal}"
// if (preferences.showSearchBar) {
// SearchBar(
// placeholder = title
// ) {
// appNavController.navigate(route)
// }
// } else {
// fab.value = @Composable {
// FloatingActionButton(
// onClick = {
// appNavController.navigate(route)
// }
// ) {
// Icon(Icons.Filled.Search, stringResource(id = R.string.preference_heading_search))
// }
// }
// }
//}

View File

@@ -13,6 +13,7 @@ import androidx.navigation.NavHostController
import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.PeopleService import com.owenlejeune.tvtime.api.tmdb.api.v3.PeopleService
import com.owenlejeune.tvtime.ui.components.PeoplePosterGrid import com.owenlejeune.tvtime.ui.components.PeoplePosterGrid
import com.owenlejeune.tvtime.ui.components.SearchView
import com.owenlejeune.tvtime.ui.navigation.MainNavItem import com.owenlejeune.tvtime.ui.navigation.MainNavItem
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -22,13 +23,21 @@ import kotlinx.coroutines.withContext
@Composable @Composable
fun PeopleTab( fun PeopleTab(
appBarTitle: MutableState<String>, appBarTitle: MutableState<String>,
appNavController: NavHostController appNavController: NavHostController,
fab: MutableState<@Composable () -> Unit>
) { ) {
appBarTitle.value = stringResource(id = R.string.nav_people_title) appBarTitle.value = stringResource(id = R.string.nav_people_title)
val service = PeopleService() val service = PeopleService()
Column { Column {
SearchView(
title = appBarTitle.value,
appNavController = appNavController,
mediaType = MediaViewType.PERSON,
fab = fab
)
Text( Text(
modifier = Modifier.padding(start = 16.dp), modifier = Modifier.padding(start = 16.dp),
text = stringResource(id = R.string.nav_popular_people_title), text = stringResource(id = R.string.nav_popular_people_title),

View File

@@ -4,12 +4,8 @@ import android.os.Build
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.rememberSplineBasedDecay import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.material.TextButton import androidx.compose.material.TextButton
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
@@ -18,15 +14,12 @@ import androidx.compose.material.icons.outlined.DarkMode
import androidx.compose.material.icons.outlined.LightMode import androidx.compose.material.icons.outlined.LightMode
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Divider
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -40,11 +33,9 @@ import com.owenlejeune.tvtime.BuildConfig
import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.preferences.AppPreferences import com.owenlejeune.tvtime.preferences.AppPreferences
import com.owenlejeune.tvtime.ui.components.* import com.owenlejeune.tvtime.ui.components.*
import com.owenlejeune.tvtime.ui.navigation.BottomNavItem
import com.owenlejeune.tvtime.ui.navigation.MainNavItem import com.owenlejeune.tvtime.ui.navigation.MainNavItem
import com.owenlejeune.tvtime.utils.ResourceUtils import com.owenlejeune.tvtime.utils.ResourceUtils
import com.owenlejeune.tvtime.utils.SessionManager import com.owenlejeune.tvtime.utils.SessionManager
import dev.kdrag0n.monet.factory.ColorSchemeFactory
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.inject import org.koin.core.component.inject
@@ -196,28 +187,16 @@ private fun TopLevelSettingsCard(
private fun SearchPreferences( private fun SearchPreferences(
preferences: AppPreferences = get(AppPreferences::class.java) preferences: AppPreferences = get(AppPreferences::class.java)
) { ) {
val persistentSearch = remember { mutableStateOf(preferences.persistentSearch) } val persistentSearch = remember { mutableStateOf(preferences.showSearchBar) }
SwitchPreference( SwitchPreference(
titleText = stringResource(R.string.preferences_persistent_search_title), titleText = stringResource(R.string.preferences_persistent_search_title),
subtitleText = stringResource(R.string.preferences_persistent_search_subtitle), subtitleText = stringResource(R.string.preferences_persistent_search_subtitle),
checkState = persistentSearch.value, checkState = persistentSearch.value,
onCheckedChange = { isChecked -> onCheckedChange = { isChecked ->
persistentSearch.value = isChecked persistentSearch.value = isChecked
preferences.persistentSearch = isChecked preferences.showSearchBar = isChecked
} }
) )
val hideTitle = remember { mutableStateOf(preferences.hideTitle) }
SwitchPreference(
titleText = stringResource(R.string.preferences_hide_heading_title),
subtitleText = stringResource(R.string.preferences_hide_heading_subtitle),
checkState = hideTitle.value,
onCheckedChange = { isChecked ->
hideTitle.value = isChecked
preferences.hideTitle = isChecked
},
enabled = persistentSearch.value
)
} }
@Composable @Composable
@@ -359,6 +338,17 @@ private fun DevPreferences(
val context = LocalContext.current val context = LocalContext.current
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
val showBackdropGallery = remember { mutableStateOf(preferences.showBackdropGallery) }
SwitchPreference(
titleText = "Show backdrop gallery",
subtitleText = "Show galleries for movies/tv backdrops",
checkState = showBackdropGallery.value,
onCheckedChange = { isChecked ->
showBackdropGallery.value = isChecked
preferences.showBackdropGallery = isChecked
}
)
val firstLaunchTesting = remember { mutableStateOf(preferences.firstLaunchTesting) } val firstLaunchTesting = remember { mutableStateOf(preferences.firstLaunchTesting) }
SwitchPreference( SwitchPreference(
titleText = "Always show onboarding flow", titleText = "Always show onboarding flow",

View File

@@ -49,10 +49,8 @@
<!-- preferences --> <!-- preferences -->
<string name="preference_heading_search">Search</string> <string name="preference_heading_search">Search</string>
<string name="preferences_persistent_search_title">Persistent search bar</string> <string name="preferences_persistent_search_title">Show search bar</string>
<string name="preferences_persistent_search_subtitle">Keep search bar visible at all times</string> <string name="preferences_persistent_search_subtitle">Show a search bar instead of a search fab</string>
<string name="preferences_hide_heading_title">Expanded search bar</string>
<string name="preferences_hide_heading_subtitle">Keep search bar expanded at all times</string>
<string name="preferences_debug_title">Developer options</string> <string name="preferences_debug_title">Developer options</string>
<string name="preference_heading_design">Design</string> <string name="preference_heading_design">Design</string>
<string name="preference_system_colors_heading">Use system colors</string> <string name="preference_system_colors_heading">Use system colors</string>