diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 32e4374..ceef3fe 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -13,15 +13,25 @@
android:supportsRtl="true"
android:theme="@style/Theme.TVTime"
android:usesCleartextTraffic="true">
+
+
+
+
+
+
+
+
+
+
-
-
-
-
diff --git a/app/src/main/java/com/owenlejeune/tvtime/AppRoutingActivity.kt b/app/src/main/java/com/owenlejeune/tvtime/AppRoutingActivity.kt
new file mode 100644
index 0000000..13f91a4
--- /dev/null
+++ b/app/src/main/java/com/owenlejeune/tvtime/AppRoutingActivity.kt
@@ -0,0 +1,23 @@
+package com.owenlejeune.tvtime
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import com.owenlejeune.tvtime.extensions.launchActivity
+import com.owenlejeune.tvtime.preferences.AppPreferences
+import org.koin.android.ext.android.inject
+
+class AppRoutingActivity: AppCompatActivity() {
+
+ private val preferences: AppPreferences by inject()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ if (preferences.firstLaunch) {
+ launchActivity(OnboardingActivity::class.java)
+ } else {
+ launchActivity(MainActivity::class.java)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt b/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt
index 0c7645b..c86e510 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt
@@ -1,7 +1,6 @@
package com.owenlejeune.tvtime
import android.os.Bundle
-import android.widget.Toast
import androidx.activity.compose.setContent
import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.foundation.Image
@@ -37,9 +36,9 @@ import com.owenlejeune.tvtime.ui.components.SearchFab
import com.owenlejeune.tvtime.ui.navigation.BottomNavItem
import com.owenlejeune.tvtime.ui.navigation.MainNavGraph
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
-import com.owenlejeune.tvtime.ui.screens.MediaDetailView
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
-import com.owenlejeune.tvtime.ui.screens.PersonDetailView
+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.theme.TVTimeTheme
import com.owenlejeune.tvtime.utils.KeyboardManager
import com.owenlejeune.tvtime.utils.SessionManager
diff --git a/app/src/main/java/com/owenlejeune/tvtime/OnboardingActivity.kt b/app/src/main/java/com/owenlejeune/tvtime/OnboardingActivity.kt
new file mode 100644
index 0000000..56dcf46
--- /dev/null
+++ b/app/src/main/java/com/owenlejeune/tvtime/OnboardingActivity.kt
@@ -0,0 +1,156 @@
+package com.owenlejeune.tvtime
+
+import android.os.Bundle
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowForward
+import androidx.compose.material3.Button
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.lifecycle.lifecycleScope
+import com.google.accompanist.pager.*
+import com.kieronquinn.monetcompat.app.MonetCompatActivity
+import com.owenlejeune.tvtime.extensions.launchActivity
+import com.owenlejeune.tvtime.preferences.AppPreferences
+import com.owenlejeune.tvtime.ui.screens.onboarding.OnboardingPage
+import com.owenlejeune.tvtime.ui.theme.TVTimeTheme
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import org.koin.android.ext.android.inject
+
+@OptIn(ExperimentalPagerApi::class)
+class OnboardingActivity: MonetCompatActivity() {
+
+ private val preferences: AppPreferences by inject()
+
+ private lateinit var pagerState: PagerState
+ private lateinit var coroutineScope: CoroutineScope
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ lifecycleScope.launchWhenCreated {
+ monet.awaitMonetReady()
+ setContent {
+ TVTimeTheme(monetCompat = monet) {
+ OnboardingUi()
+ }
+ }
+ }
+ }
+
+ @Composable
+ fun OnboardingUi() {
+ pagerState = rememberPagerState()
+ coroutineScope = rememberCoroutineScope()
+
+ Column(
+ modifier = Modifier.background(color = MaterialTheme.colorScheme.background)
+ ) {
+ HorizontalPager(
+ state = pagerState,
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(1f),
+// .background(MaterialTheme.colorScheme.primary),
+ count = OnboardingPage.values().size,
+ userScrollEnabled = false
+ ) { page ->
+ OnboardingPageUi(page = OnboardingPage[page])
+ }
+
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(all = 12.dp)
+ ) {
+ HorizontalPagerIndicator(
+ pagerState = pagerState,
+ modifier = Modifier
+ .align(Alignment.Center)
+ .padding(16.dp),
+ activeColor = MaterialTheme.colorScheme.secondary
+ )
+
+ val isLastPage = pagerState.currentPage == OnboardingPage.values().size - 1
+ Button(
+ modifier = Modifier.align(Alignment.CenterEnd),
+ shape = CircleShape,
+ onClick = {
+ if (isLastPage) {
+ preferences.firstLaunch = false
+ launchActivity(MainActivity::class.java)
+ } else {
+ coroutineScope.launch {
+ pagerState.animateScrollToPage(pagerState.currentPage + 1)
+ }
+ }
+ }
+ ) {
+ if (isLastPage) {
+ Text(stringResource(id = R.string.get_started))
+ } else {
+ Icon(imageVector = Icons.Filled.ArrowForward, contentDescription = null)
+ }
+ }
+ }
+ }
+ }
+
+ @Composable
+ fun OnboardingPageUi(page: OnboardingPage) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ page.image?.let {
+ Image(
+ painter = painterResource(id = it),
+ contentDescription = null,
+ modifier = Modifier.size(200.dp),
+ colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.secondary)
+ )
+ Spacer(modifier = Modifier.height(20.dp))
+ }
+ Text(
+ text = stringResource(id = page.title),
+ fontSize = 28.sp,
+ fontWeight = FontWeight.Bold,
+ color = MaterialTheme.colorScheme.onBackground
+ )
+ Spacer(modifier = Modifier.height(8.dp))
+ Text(
+ text = stringResource(id = page.description),
+ textAlign = TextAlign.Center,
+ fontSize = 14.sp,
+ color = MaterialTheme.colorScheme.onBackground
+ )
+ Spacer(modifier = Modifier.height(12.dp))
+ page.additionalContent(this@OnboardingActivity)
+ }
+ }
+
+ override fun onBackPressed() {
+ if (pagerState.currentPage == 0) {
+ finish()
+ } else {
+ coroutineScope.launch {
+ pagerState.animateScrollToPage(pagerState.currentPage - 1)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/owenlejeune/tvtime/TvTimeApplication.kt b/app/src/main/java/com/owenlejeune/tvtime/TvTimeApplication.kt
index 864b286..f61a824 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/TvTimeApplication.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/TvTimeApplication.kt
@@ -6,6 +6,9 @@ import com.kieronquinn.monetcompat.core.MonetCompat
import com.owenlejeune.tvtime.di.modules.appModule
import com.owenlejeune.tvtime.di.modules.networkModule
import com.owenlejeune.tvtime.di.modules.preferencesModule
+import com.owenlejeune.tvtime.preferences.AppPreferences
+import dev.kdrag0n.monet.factory.ColorSchemeFactory
+import org.koin.android.ext.android.inject
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
@@ -13,6 +16,8 @@ import org.koin.core.logger.Level
class TvTimeApplication: Application() {
+ private val preferences: AppPreferences by inject()
+
override fun onCreate() {
super.onCreate()
@@ -30,6 +35,12 @@ class TvTimeApplication: Application() {
}
MonetCompat.enablePaletteCompat()
+ MonetCompat.chromaMultiplier = preferences.chromaMultiplier
+
+ MonetCompat.wallpaperColorPicker = {
+ val userPickedColor = preferences.selectedColor
+ it?.firstOrNull { color -> color == userPickedColor } ?: it?.firstOrNull()
+ }
if (BuildConfig.DEBUG) {
Stetho.initializeWithDefaults(this)
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/deserializer/KnownForDeserializer.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/deserializer/KnownForDeserializer.kt
index cb6da5d..bd00477 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/deserializer/KnownForDeserializer.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/deserializer/KnownForDeserializer.kt
@@ -2,7 +2,7 @@ package com.owenlejeune.tvtime.api.tmdb.api.v3.deserializer
import com.google.gson.*
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.KnownFor
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
import java.lang.reflect.Type
class KnownForDeserializer: JsonDeserializer {
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/DetailCast.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/DetailCast.kt
index 9d171ee..04f84ff 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/DetailCast.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/DetailCast.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v3.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class DetailCast(
@SerializedName("id") val id: Int,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/DetailCrew.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/DetailCrew.kt
index d0a41c7..93762d3 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/DetailCrew.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/DetailCrew.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v3.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class DetailCrew(
@SerializedName("id") val id: Int,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnowForTv.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnowForTv.kt
index fb17ccb..ce4762d 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnowForTv.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnowForTv.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v3.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class KnowForTv(
backdropPath: String?,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnownFor.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnownFor.kt
index 37cbb6c..f83f5e9 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnownFor.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnownFor.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v3.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
abstract class KnownFor(
@SerializedName("backdrop_path") val backdropPath: String?,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnownForMovie.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnownForMovie.kt
index 8f49e17..cc77622 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnownForMovie.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/KnownForMovie.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v3.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class KnownForMovie(
backdropPath: String?,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/MarkAsFavoriteBody.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/MarkAsFavoriteBody.kt
index 42b2e3b..8a3be6c 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/MarkAsFavoriteBody.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/MarkAsFavoriteBody.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v3.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class MarkAsFavoriteBody(
@SerializedName("media_type") val mediaType: MediaViewType,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/WatchlistBody.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/WatchlistBody.kt
index 21d4947..e434fdd 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/WatchlistBody.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v3/model/WatchlistBody.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v3.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class WatchlistBody(
@SerializedName("media_type") val mediaType: MediaViewType,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/deserializer/ListItemDeserializer.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/deserializer/ListItemDeserializer.kt
index f7eac33..c8d4c07 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/deserializer/ListItemDeserializer.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/deserializer/ListItemDeserializer.kt
@@ -4,7 +4,7 @@ import com.google.gson.*
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.ListItem
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.ListMovie
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.ListTv
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
import java.lang.reflect.Type
class ListItemDeserializer: JsonDeserializer {
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/AddToListBodyItem.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/AddToListBodyItem.kt
index 9844173..253e2c2 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/AddToListBodyItem.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/AddToListBodyItem.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class AddToListBody(
@SerializedName("items") val items: List
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/DeleteListItemsBody.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/DeleteListItemsBody.kt
index cc0707f..215d460 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/DeleteListItemsBody.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/DeleteListItemsBody.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class DeleteListItemsBody(
@SerializedName("media_id") val id: Int,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItem.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItem.kt
index fb31713..942ad2d 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItem.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItem.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
abstract class ListItem(
@SerializedName("backdrop_path") val backdropPath: String?,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItemStatusResponse.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItemStatusResponse.kt
index e997d08..8167bef 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItemStatusResponse.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListItemStatusResponse.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class ListItemStatusResponse(
statusMessage: String,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListMovie.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListMovie.kt
index e6fa6e8..bdf91eb 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListMovie.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListMovie.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class ListMovie(
backdropPath: String?,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListTv.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListTv.kt
index c267e68..713203f 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListTv.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/ListTv.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class ListTv(
backdropPath: String?,
diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/UpdateListItemBody.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/UpdateListItemBody.kt
index b751210..b2df822 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/UpdateListItemBody.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/model/UpdateListItemBody.kt
@@ -1,7 +1,7 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4.model
import com.google.gson.annotations.SerializedName
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class UpdateListItemBody(
@SerializedName("items") val items: List
diff --git a/app/src/main/java/com/owenlejeune/tvtime/extensions/ActivityExtensions.kt b/app/src/main/java/com/owenlejeune/tvtime/extensions/ActivityExtensions.kt
index 1fa2829..94022cd 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/extensions/ActivityExtensions.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/extensions/ActivityExtensions.kt
@@ -1,6 +1,7 @@
package com.owenlejeune.tvtime.extensions
import android.app.Activity
+import android.content.Intent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.geometry.Size
@@ -39,4 +40,10 @@ private fun getWindowSizeClass(windowDpSize: DpSize): WindowSizeClass = when {
windowDpSize.width < 600.dp -> WindowSizeClass.Compact
windowDpSize.width < 840.dp -> WindowSizeClass.Medium
else -> WindowSizeClass.Expanded
+}
+
+fun Activity.launchActivity(activity: Class) {
+ val intent = Intent(this, activity)
+ startActivity(intent)
+ finish()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/owenlejeune/tvtime/preferences/AppPreferences.kt b/app/src/main/java/com/owenlejeune/tvtime/preferences/AppPreferences.kt
index 49b1cac..88f4c3a 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/preferences/AppPreferences.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/preferences/AppPreferences.kt
@@ -2,6 +2,8 @@ package com.owenlejeune.tvtime.preferences
import android.content.Context
import android.content.SharedPreferences
+import com.kieronquinn.monetcompat.core.MonetCompat
+import com.owenlejeune.tvtime.BuildConfig
class AppPreferences(context: Context) {
@@ -13,6 +15,11 @@ class AppPreferences(context: Context) {
private val HIDE_TITLE = "hide_title"
private val GUEST_SESSION = "guest_session_id"
private val AUTHORIZED_SESSION = "authorized_session_id"
+ private val FIRST_LAUNCH = "first_launch"
+ private val FIRST_LAUNCH_TESTING = "first_launch_testing"
+ private val CHROMA_MULTIPLIER = "chroma_multiplier"
+ private val USE_SYSTEM_COLORS = "use_system_colors"
+ private val SELECTED_COLOR = "selected_color"
}
private val preferences: SharedPreferences = context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE)
@@ -37,6 +44,26 @@ class AppPreferences(context: Context) {
// get() = preferences.getBoolean(USE_PREFERENCES, false)
// set(value) { preferences.put(USE_PREFERENCES, value) }
+ var firstLaunchTesting: Boolean
+ get() = preferences.getBoolean(FIRST_LAUNCH_TESTING, false)
+ set(value) { preferences.put(FIRST_LAUNCH_TESTING, value) }
+
+ var firstLaunch: Boolean
+ get() = if (BuildConfig.DEBUG) firstLaunchTesting else preferences.getBoolean(FIRST_LAUNCH, true)
+ set(value) { preferences.put(FIRST_LAUNCH, value) }
+
+ var useSystemColors: Boolean
+ get() = preferences.getBoolean(USE_SYSTEM_COLORS, true)
+ set(value) { preferences.put(USE_SYSTEM_COLORS, value) }
+
+ var chromaMultiplier: Double
+ get() = preferences.getFloat(CHROMA_MULTIPLIER, MonetCompat.chromaMultiplier.toFloat()).toDouble()
+ set(value) { preferences.put(CHROMA_MULTIPLIER, value) }
+
+ var selectedColor: Int
+ get() = preferences.getInt(SELECTED_COLOR, Int.MAX_VALUE)
+ set(value) { preferences.put(SELECTED_COLOR, value) }
+
private fun SharedPreferences.put(key: String, value: Any?) {
edit().apply {
when (value) {
@@ -44,12 +71,16 @@ class AppPreferences(context: Context) {
is Int -> putInt(key, value)
is Long -> putLong(key, value)
is Float -> putFloat(key, value)
+ is Double -> putFloat(key, value.toFloat())
is String -> putString(key, value)
+ else -> throw UnsupportedTypeError()
}
apply()
}
}
+ class UnsupportedTypeError: Exception()
+
// private fun SharedPreferences.get(key: String, java: Class): T {
//
// }
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/components/PreferenceWidgets.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/components/PreferenceWidgets.kt
index 835c28e..0c42a2c 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/components/PreferenceWidgets.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/components/PreferenceWidgets.kt
@@ -1,9 +1,11 @@
package com.owenlejeune.tvtime.ui.components
import androidx.compose.foundation.layout.*
+import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Slider
import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
+import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -73,4 +75,41 @@ fun SwitchPreference(
@Composable
private fun SwitchPreferencePreview() {
SwitchPreference("Title", true, subtitleText = "Subtitle")
+}
+
+@Composable
+fun SliderPreference(
+ modifier: Modifier = Modifier,
+ titleText: String,
+ value: Float,
+ onValueChangeFinished: (Float) -> Unit ,
+ titleTextColor: Color = MaterialTheme.colorScheme.onBackground,
+ disabledTextColor: Color = MaterialTheme.colorScheme.outline,
+ enabled: Boolean = true
+) {
+ Column(
+ modifier = modifier
+ .wrapContentHeight()
+ .padding(all = 8.dp)
+ ) {
+ val titleColor = if (enabled) titleTextColor else disabledTextColor
+ Text(text = titleText, style = MaterialTheme.typography.titleLarge, color = titleColor, fontSize = 20.sp)
+
+ var sliderValue by remember { mutableStateOf(value) }
+
+ Slider(
+ modifier = Modifier.fillMaxWidth().padding(start = 8.dp),
+ value = sliderValue,
+ onValueChange = { sliderValue = it },
+ enabled = enabled,
+ valueRange = 0f..100f,
+ onValueChangeFinished = {
+ onValueChangeFinished(sliderValue)
+ },
+ colors = SliderDefaults.colors(
+ thumbColor = MaterialTheme.colorScheme.primary,
+ activeTrackColor = MaterialTheme.colorScheme.primary
+ )
+ )
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt
index 9df7452..7aefd89 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/components/Widgets.kt
@@ -20,10 +20,7 @@ import androidx.compose.material.Card
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.TextFieldDefaults
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Error
-import androidx.compose.material.icons.filled.Search
-import androidx.compose.material.icons.filled.Visibility
-import androidx.compose.material.icons.filled.VisibilityOff
+import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
@@ -65,6 +62,7 @@ import androidx.core.text.HtmlCompat
import coil.compose.AsyncImage
import coil.compose.rememberAsyncImagePainter
import com.google.accompanist.flowlayout.FlowRow
+import com.kieronquinn.monetcompat.core.MonetCompat
import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.AuthorDetails
import com.owenlejeune.tvtime.ui.theme.RatingSelected
@@ -924,4 +922,40 @@ fun TimeoutSnackbar(
onDismiss()
}
}
+}
+
+@Composable
+fun CenteredIconCircle(
+ size: Dp,
+ backgroundColor: Color,
+ iconTint: Color,
+ icon: ImageVector,
+ contentDescription: String?,
+ showIcon: Boolean = true,
+ onClick: () -> Unit = {}
+) {
+ Box(
+ modifier = Modifier
+ .size(size)
+ .clip(CircleShape)
+ .background(color = backgroundColor)
+ .clickable {
+ onClick()
+ }
+ ) {
+ if (showIcon) {
+ Column(
+ modifier = Modifier.size(size),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Icon(
+ imageVector = icon,
+ contentDescription = contentDescription,
+ modifier = Modifier.size(size / 2),
+ tint = iconTint
+ )
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AccountTabNavItem.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AccountTabNavItem.kt
index 7161d2a..6a5aa1e 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AccountTabNavItem.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AccountTabNavItem.kt
@@ -4,8 +4,8 @@ import androidx.compose.runtime.Composable
import androidx.navigation.NavHostController
import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.*
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
-import com.owenlejeune.tvtime.ui.screens.tabs.bottom.AccountTabContent
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.AccountTabContent
import com.owenlejeune.tvtime.utils.ResourceUtils
import com.owenlejeune.tvtime.utils.SessionManager
import org.koin.core.component.inject
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/MediaTabNavItem.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/MediaTabNavItem.kt
index 0d9a23d..61e9c22 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/MediaTabNavItem.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/MediaTabNavItem.kt
@@ -5,8 +5,8 @@ import androidx.navigation.NavHostController
import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.HomePageService
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePageResponse
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
-import com.owenlejeune.tvtime.ui.screens.tabs.bottom.MediaTabContent
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.MediaTabContent
import com.owenlejeune.tvtime.utils.ResourceUtils
import org.koin.core.component.inject
import retrofit2.Response
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/Routes.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/Routes.kt
index 0049745..a37cea0 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/Routes.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/Routes.kt
@@ -9,11 +9,9 @@ import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
-import com.owenlejeune.tvtime.ui.screens.MediaDetailView
-import com.owenlejeune.tvtime.ui.screens.MainAppView
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
-import com.owenlejeune.tvtime.ui.screens.PersonDetailView
-import com.owenlejeune.tvtime.ui.screens.tabs.bottom.*
+import com.owenlejeune.tvtime.ui.screens.main.MediaDetailView
+import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
+import com.owenlejeune.tvtime.ui.screens.main.*
object NavConstants {
const val ID_KEY = "id_key"
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/AccountTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt
similarity index 98%
rename from app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/AccountTab.kt
rename to app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt
index 50d21e5..568a511 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/AccountTab.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt
@@ -1,4 +1,4 @@
-package com.owenlejeune.tvtime.ui.screens.tabs.bottom
+package com.owenlejeune.tvtime.ui.screens.main
import android.content.Context
import androidx.compose.foundation.clickable
@@ -12,7 +12,6 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@@ -29,8 +28,7 @@ import com.owenlejeune.tvtime.ui.components.*
import com.owenlejeune.tvtime.ui.navigation.AccountTabNavItem
import com.owenlejeune.tvtime.ui.navigation.ListFetchFun
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
-import com.owenlejeune.tvtime.ui.screens.tabs.top.ScrollableTabs
+import com.owenlejeune.tvtime.ui.screens.main.tabs.top.ScrollableTabs
import com.owenlejeune.tvtime.utils.SessionManager
import com.owenlejeune.tvtime.utils.TmdbUtils
import kotlinx.coroutines.CoroutineScope
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/DetailViewCommon.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/DetailViewCommon.kt
similarity index 99%
rename from app/src/main/java/com/owenlejeune/tvtime/ui/screens/DetailViewCommon.kt
rename to app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/DetailViewCommon.kt
index c89a1e5..a84c779 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/DetailViewCommon.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/DetailViewCommon.kt
@@ -1,4 +1,4 @@
-package com.owenlejeune.tvtime.ui.screens
+package com.owenlejeune.tvtime.ui.screens.main
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/FavouritesTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/FavouritesTab.kt
similarity index 92%
rename from app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/FavouritesTab.kt
rename to app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/FavouritesTab.kt
index 0f771c7..279e30c 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/FavouritesTab.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/FavouritesTab.kt
@@ -1,4 +1,4 @@
-package com.owenlejeune.tvtime.ui.screens.tabs.bottom
+package com.owenlejeune.tvtime.ui.screens.main
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/MainView.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MainView.kt
similarity index 99%
rename from app/src/main/java/com/owenlejeune/tvtime/ui/screens/MainView.kt
rename to app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MainView.kt
index 0c260b8..e7a7798 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/MainView.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MainView.kt
@@ -1,4 +1,4 @@
-package com.owenlejeune.tvtime.ui.screens
+package com.owenlejeune.tvtime.ui.screens.main
import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.foundation.Image
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/MediaDetailView.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaDetailView.kt
similarity index 99%
rename from app/src/main/java/com/owenlejeune/tvtime/ui/screens/MediaDetailView.kt
rename to app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaDetailView.kt
index 494ac1e..7590974 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/MediaDetailView.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaDetailView.kt
@@ -1,17 +1,13 @@
-package com.owenlejeune.tvtime.ui.screens
+package com.owenlejeune.tvtime.ui.screens.main
import android.content.Context
import android.widget.Toast
import androidx.compose.animation.*
-import androidx.compose.animation.core.LinearOutSlowInEasing
-import androidx.compose.animation.core.keyframes
-import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Send
@@ -29,7 +25,6 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.DpSize
-import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/MediaTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaTab.kt
similarity index 95%
rename from app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/MediaTab.kt
rename to app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaTab.kt
index 141ab0b..48a6b4d 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/MediaTab.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaTab.kt
@@ -1,4 +1,4 @@
-package com.owenlejeune.tvtime.ui.screens.tabs.bottom
+package com.owenlejeune.tvtime.ui.screens.main
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
@@ -16,8 +16,7 @@ import com.owenlejeune.tvtime.ui.components.PosterGrid
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
import com.owenlejeune.tvtime.ui.navigation.MediaFetchFun
import com.owenlejeune.tvtime.ui.navigation.MediaTabNavItem
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
-import com.owenlejeune.tvtime.ui.screens.tabs.top.Tabs
+import com.owenlejeune.tvtime.ui.screens.main.tabs.top.Tabs
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/MediaViewType.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViewType.kt
similarity index 79%
rename from app/src/main/java/com/owenlejeune/tvtime/ui/screens/MediaViewType.kt
rename to app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViewType.kt
index 0454549..d4ede70 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/MediaViewType.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViewType.kt
@@ -1,4 +1,4 @@
-package com.owenlejeune.tvtime.ui.screens
+package com.owenlejeune.tvtime.ui.screens.main
import com.google.gson.annotations.SerializedName
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/PeopleDetailView.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/PeopleDetailView.kt
similarity index 99%
rename from app/src/main/java/com/owenlejeune/tvtime/ui/screens/PeopleDetailView.kt
rename to app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/PeopleDetailView.kt
index 411e6eb..54b41ef 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/PeopleDetailView.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/PeopleDetailView.kt
@@ -1,4 +1,4 @@
-package com.owenlejeune.tvtime.ui.screens
+package com.owenlejeune.tvtime.ui.screens.main
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/PeopleTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/PeopleTab.kt
similarity index 94%
rename from app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/PeopleTab.kt
rename to app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/PeopleTab.kt
index 409b4ad..4447fa3 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/PeopleTab.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/PeopleTab.kt
@@ -1,4 +1,4 @@
-package com.owenlejeune.tvtime.ui.screens.tabs.bottom
+package com.owenlejeune.tvtime.ui.screens.main
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
@@ -14,7 +14,6 @@ import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.PeopleService
import com.owenlejeune.tvtime.ui.components.PeoplePosterGrid
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
-import com.owenlejeune.tvtime.ui.screens.MediaViewType
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/SettingsTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/SettingsTab.kt
new file mode 100644
index 0000000..f10ee90
--- /dev/null
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/SettingsTab.kt
@@ -0,0 +1,296 @@
+package com.owenlejeune.tvtime.ui.screens.main
+
+import android.os.Build
+import android.widget.Toast
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+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.TextButton
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Check
+import androidx.compose.material.icons.filled.ResetTv
+import androidx.compose.material.icons.filled.RestartAlt
+import androidx.compose.material3.*
+import androidx.compose.material3.AlertDialog
+import androidx.compose.material3.Divider
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.Icon
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.kieronquinn.monetcompat.core.MonetCompat
+import com.owenlejeune.tvtime.BuildConfig
+import com.owenlejeune.tvtime.R
+import com.owenlejeune.tvtime.preferences.AppPreferences
+import com.owenlejeune.tvtime.ui.components.*
+import com.owenlejeune.tvtime.utils.SessionManager
+import dev.kdrag0n.monet.factory.ColorSchemeFactory
+import kotlinx.coroutines.launch
+import org.koin.java.KoinJavaComponent.get
+
+@Composable
+fun SettingsTab(preferences: AppPreferences = get(AppPreferences::class.java)) {
+ val scrollState = rememberScrollState()
+
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(start = 8.dp, top = 8.dp, bottom = 8.dp, end = 24.dp)
+ .verticalScroll(scrollState)
+ ) {
+// val usePreferences = remember { mutableStateOf(preferences.usePreferences) }
+// TopLevelSwitch(
+// text = "Enable Preferences",
+// checkedState = usePreferences,
+// onCheckChanged = { isChecked ->
+// usePreferences.value = isChecked
+// preferences.usePreferences = isChecked
+// }
+// )
+//
+// Column(
+// modifier = Modifier
+// .fillMaxWidth()
+// .wrapContentHeight()
+// .padding(start = 8.dp, top = 8.dp, bottom = 8.dp, end = 24.dp)
+// .verticalScroll()
+// ) {
+ PreferenceHeading(text = stringResource(R.string.preference_heading_search))
+
+ val persistentSearch = remember { mutableStateOf(preferences.persistentSearch) }
+ SwitchPreference(
+ titleText = stringResource(R.string.preferences_persistent_search_title),
+ subtitleText = stringResource(R.string.preferences_persistent_search_subtitle),
+ checkState = persistentSearch.value,
+ onCheckedChange = { isChecked ->
+ persistentSearch.value = isChecked
+ preferences.persistentSearch = 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
+ )
+
+ PreferenceHeading(text = stringResource(id = R.string.preference_heading_design))
+
+ val isSystemColorsSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
+ if (isSystemColorsSupported) {
+ val useSystemColors = remember { mutableStateOf(preferences.useSystemColors) }
+ SwitchPreference(
+ titleText = stringResource(id = R.string.preference_system_colors_heading),
+ checkState = useSystemColors.value,
+ onCheckedChange = { isChecked ->
+ useSystemColors.value = isChecked
+ preferences.useSystemColors = isChecked
+ MonetCompat.useSystemColorsOnAndroid12 = isChecked
+ MonetCompat.getInstance().updateMonetColors()
+ }
+ )
+ }
+
+ SliderPreference(
+ titleText = stringResource(id = R.string.preference_chroma_factor_heading),
+ value = preferences.chromaMultiplier.toFloat() * 50f,
+ onValueChangeFinished = { value ->
+ with((value / 50f).toDouble()) {
+ preferences.chromaMultiplier = this
+ MonetCompat.chromaMultiplier = this
+ }
+ MonetCompat.getInstance().updateMonetColors()
+ },
+ enabled = if (isSystemColorsSupported) !preferences.useSystemColors else true
+ )
+
+ val showWallpaperPicker = remember { mutableStateOf(false) }
+ val wallpaperPickerModifier = if (isSystemColorsSupported && preferences.useSystemColors) {
+ Modifier
+ } else {
+ Modifier.clickable { showWallpaperPicker.value = true }
+ }
+ Text(
+ text = stringResource(id = R.string.preference_wallpaper_color_heading),
+ style = MaterialTheme.typography.titleLarge,
+ fontSize = 20.sp,
+ color = if (isSystemColorsSupported && preferences.useSystemColors) {
+ MaterialTheme.colorScheme.outline
+ } else {
+ MaterialTheme.colorScheme.onBackground
+ },
+ modifier = wallpaperPickerModifier
+ .padding(start = 8.dp)
+ )
+ if (showWallpaperPicker.value) {
+ WallpaperPicker(showPopup = showWallpaperPicker)
+ }
+
+ if (BuildConfig.DEBUG) {
+ Divider(modifier = Modifier.padding(start = 8.dp, top = 20.dp))
+ Text(
+ modifier = Modifier.padding(start = 8.dp, top = 20.dp),
+ text = stringResource(R.string.preferences_debug_title),
+ style = MaterialTheme.typography.headlineMedium,
+ color = MaterialTheme.colorScheme.primary
+ )
+ DebugOptions()
+ }
+ }
+}
+
+@Composable
+private fun WallpaperPicker(
+ showPopup: MutableState,
+ preference: AppPreferences = get(AppPreferences::class.java)
+) {
+ val context = LocalContext.current
+
+ val wallpaperColors = remember { mutableStateOf>(emptyList()) }
+ val selectedWallpaperColor = remember { mutableStateOf(0) }
+ LaunchedEffect(true) {
+ val colors = MonetCompat.getInstance().getAvailableWallpaperColors() ?: emptyList()
+ if (colors.isEmpty()) {
+ Toast.makeText(context, context.getString(R.string.preference_no_wallpaper_colors), Toast.LENGTH_SHORT).show()
+ showPopup.value = false
+
+ }
+ wallpaperColors.value = colors
+ selectedWallpaperColor.value = MonetCompat.getInstance().getSelectedWallpaperColor() ?: 0
+ }
+
+ if (wallpaperColors.value.isNotEmpty() && selectedWallpaperColor.value != 0) {
+ val colorCircleSize = 50.dp
+ AlertDialog(
+ modifier = Modifier.padding(12.dp),
+ title = { Text(text = stringResource(id = R.string.preference_wallpaper_color_heading)) },
+ text = {
+ Row(
+ modifier = Modifier
+ .height(colorCircleSize)
+ .fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceEvenly
+ ) {
+ wallpaperColors.value.forEach {
+ CenteredIconCircle(
+ size = colorCircleSize,
+ backgroundColor = Color(it),
+ iconTint = Color.White,
+ icon = Icons.Filled.Check,
+ contentDescription = null,
+ showIcon = it == selectedWallpaperColor.value,
+ onClick = {
+ if (it != selectedWallpaperColor.value) {
+ preference.selectedColor = it
+ MonetCompat
+ .getInstance()
+ .updateMonetColors()
+ }
+ }
+ )
+ }
+
+ CenteredIconCircle(
+ size = colorCircleSize,
+ backgroundColor = MaterialTheme.colorScheme.secondaryContainer,
+ iconTint = MaterialTheme.colorScheme.onSecondaryContainer,
+ icon = Icons.Filled.RestartAlt,
+ contentDescription = null,
+ onClick = {
+ if (preference.selectedColor != Int.MAX_VALUE) {
+ preference.selectedColor = Int.MAX_VALUE
+ MonetCompat.getInstance().updateMonetColors()
+ } else {
+ Toast.makeText(context, context.getString(R.string.preference_wallpaper_color_default_selected), Toast.LENGTH_SHORT).show()
+ }
+ }
+ )
+ }
+ },
+ dismissButton = {
+ TextButton(onClick = { showPopup.value = false }) {
+ Text(text = stringResource(id = R.string.action_cancel))
+ }
+ },
+ confirmButton = {},
+ onDismissRequest = { showPopup.value = false }
+ )
+ }
+}
+
+@Composable
+private fun DebugOptions(preferences: AppPreferences = get(AppPreferences::class.java)) {
+ val context = LocalContext.current
+
+ val firstLaunchTesting = remember { mutableStateOf(preferences.firstLaunchTesting) }
+ SwitchPreference(
+ titleText = "Always show onboarding flow",
+ subtitleText = "Show onboarding flow on each launch",
+ checkState = firstLaunchTesting.value,
+ onCheckedChange = { isChecked ->
+ firstLaunchTesting.value = isChecked
+ preferences.firstLaunchTesting = isChecked
+ }
+ )
+
+ val shouldShowPalette = remember { mutableStateOf(false) }
+ Text(
+ text = "Show material palette",
+ color = MaterialTheme.colorScheme.onBackground,
+ modifier = Modifier
+ .padding(horizontal = 8.dp, vertical = 12.dp)
+ .clickable(
+ onClick = {
+ shouldShowPalette.value = true
+ }
+ )
+ )
+ if (shouldShowPalette.value) {
+ AlertDialog(
+ modifier = Modifier.padding(12.dp),
+ title = { Text(text = "Palette") },
+ text = { PaletteView() },
+ dismissButton = {
+ TextButton(onClick = { shouldShowPalette.value = false }) {
+ Text("Dismiss")
+ }
+ },
+ confirmButton = {},
+ onDismissRequest = { shouldShowPalette.value = false }
+ )
+ }
+
+ Text(
+ text = "Clear session",
+ color = MaterialTheme.colorScheme.onBackground,
+ modifier = Modifier
+ .padding(horizontal = 8.dp, vertical = 12.dp)
+ .clickable(
+ onClick = {
+ preferences.guestSessionId = ""
+ SessionManager.clearSession {
+ Toast
+ .makeText(context, "Cleared session: $it", Toast.LENGTH_SHORT)
+ .show()
+ }
+ }
+ )
+ )
+}
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/top/TabsCommon.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/top/TabsCommon.kt
similarity index 98%
rename from app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/top/TabsCommon.kt
rename to app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/top/TabsCommon.kt
index 1fa24f0..64ee517 100644
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/top/TabsCommon.kt
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/top/TabsCommon.kt
@@ -1,4 +1,4 @@
-package com.owenlejeune.tvtime.ui.screens.tabs.top
+package com.owenlejeune.tvtime.ui.screens.main.tabs.top
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Spacer
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/onboarding/OnboardingPage.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/onboarding/OnboardingPage.kt
new file mode 100644
index 0000000..c5f8cb4
--- /dev/null
+++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/onboarding/OnboardingPage.kt
@@ -0,0 +1,28 @@
+package com.owenlejeune.tvtime.ui.screens.onboarding
+
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+import androidx.appcompat.app.AppCompatActivity
+import androidx.compose.runtime.Composable
+import com.owenlejeune.tvtime.R
+
+sealed class OnboardingPage(
+ @StringRes val title: Int,
+ @StringRes val description: Int,
+ @DrawableRes val image: Int? = null,
+ val additionalContent: @Composable (AppCompatActivity) -> Unit = {}
+) {
+
+ companion object {
+ fun values() = listOf(ExamplePage)
+
+ operator fun get(i: Int) = values()[i]
+ }
+
+ object ExamplePage: OnboardingPage(
+ R.string.app_name,
+ R.string.example_page_desc,
+ R.drawable.ic_launcher_foreground
+ )
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/SettingsTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/SettingsTab.kt
deleted file mode 100644
index fbc1a19..0000000
--- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/SettingsTab.kt
+++ /dev/null
@@ -1,145 +0,0 @@
-package com.owenlejeune.tvtime.ui.screens.tabs.bottom
-
-import android.widget.Toast
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.verticalScroll
-import androidx.compose.material.Switch
-import androidx.compose.material.TextButton
-import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Button
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.unit.dp
-import com.owenlejeune.tvtime.BuildConfig
-import com.owenlejeune.tvtime.R
-import com.owenlejeune.tvtime.di.modules.preferencesModule
-import com.owenlejeune.tvtime.preferences.AppPreferences
-import com.owenlejeune.tvtime.ui.components.*
-import com.owenlejeune.tvtime.utils.SessionManager
-import org.koin.java.KoinJavaComponent.get
-
-@Composable
-fun SettingsTab(preferences: AppPreferences = get(AppPreferences::class.java)) {
- val scrollState = rememberScrollState()
-
- Column(modifier = Modifier
- .fillMaxSize()
- .padding(start = 8.dp, top = 8.dp, bottom = 8.dp, end = 24.dp)
- .verticalScroll(scrollState)
- ) {
-// val usePreferences = remember { mutableStateOf(preferences.usePreferences) }
-// TopLevelSwitch(
-// text = "Enable Preferences",
-// checkedState = usePreferences,
-// onCheckChanged = { isChecked ->
-// usePreferences.value = isChecked
-// preferences.usePreferences = isChecked
-// }
-// )
-//
-// Column(
-// modifier = Modifier
-// .fillMaxWidth()
-// .wrapContentHeight()
-// .padding(start = 8.dp, top = 8.dp, bottom = 8.dp, end = 24.dp)
-// .verticalScroll()
-// ) {
- PreferenceHeading(text = stringResource(R.string.preference_heading_search))
-
- val persistentSearch = remember { mutableStateOf(preferences.persistentSearch) }
- SwitchPreference(
- titleText = stringResource(R.string.preferences_persistent_search_title),
- subtitleText = stringResource(R.string.preferences_persistent_search_subtitle),
- checkState = persistentSearch.value,
- onCheckedChange = { isChecked ->
- persistentSearch.value = isChecked
- preferences.persistentSearch = 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
- )
-
- if (BuildConfig.DEBUG) {
- Text(
- modifier = Modifier.padding(start = 8.dp, top = 20.dp),
- text = stringResource(R.string.preferences_debug_title),
- style = MaterialTheme.typography.headlineSmall,
- color = MaterialTheme.colorScheme.onBackground
- )
- DebugOptions()
- }
- }
-}
-
-@Composable
-private fun DebugOptions(preferences: AppPreferences = get(AppPreferences::class.java)) {
- val context = LocalContext.current
- val shouldShowPalette = remember { mutableStateOf(false) }
- Text(
- text = "Show material palette",
- color = MaterialTheme.colorScheme.onBackground,
- modifier = Modifier
- .padding(horizontal = 8.dp, vertical = 12.dp)
- .clickable(
- onClick = {
- shouldShowPalette.value = true
- }
- )
- )
- if (shouldShowPalette.value) {
- PaletteDialog(shouldShowPalette)
- }
-
- Text(
- text = "Clear session",
- color = MaterialTheme.colorScheme.onBackground,
- modifier = Modifier
- .padding(horizontal = 8.dp, vertical = 12.dp)
- .clickable(
- onClick = {
- preferences.guestSessionId = ""
- SessionManager.clearSession {
- Toast.makeText(context, "Cleared session: $it", Toast.LENGTH_SHORT).show()
- }
- }
- )
- )
-}
-
-@Composable
-private fun PaletteDialog(showDialog: MutableState) {
- AlertDialog(
- modifier = Modifier.padding(12.dp),
- title = { Text(text = "Palette") },
- text = { PaletteView() },
- dismissButton = {
- TextButton(onClick = { showDialog.value = false }) {
- Text("Dismiss")
- }
- },
- confirmButton = {},
- onDismissRequest = { showDialog.value = false }
- )
-}
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0606b8b..42d6988 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -54,6 +54,12 @@
Expanded search bar
Keep search bar expanded at all times
Developer options
+ Design
+ Use system colors
+ Saturation
+ Wallpaper Color Picker
+ Unavailable for the current wallpaper or your current settings
+ Wallpaper color already set to default
Clips
@@ -104,4 +110,8 @@
tvtime.auth.return
+
+
+ Get started
+ This is an example
\ No newline at end of file