mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-09 13:22:44 -05:00
add items to about page and add attribution
This commit is contained in:
@@ -33,8 +33,8 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '1.8'
|
jvmTarget = '1.8'
|
||||||
@@ -118,7 +118,7 @@ dependencies {
|
|||||||
implementation "io.insert-koin:koin-android:$koin"
|
implementation "io.insert-koin:koin-android:$koin"
|
||||||
|
|
||||||
// coil
|
// coil
|
||||||
def coil = "2.0.0-rc01"
|
def coil = "2.2.2"
|
||||||
implementation "io.coil-kt:coil-compose:$coil"
|
implementation "io.coil-kt:coil-compose:$coil"
|
||||||
|
|
||||||
//Coroutines
|
//Coroutines
|
||||||
@@ -135,9 +135,11 @@ dependencies {
|
|||||||
def markdown = "0.2.1"
|
def markdown = "0.2.1"
|
||||||
implementation "org.jetbrains:markdown:$markdown"
|
implementation "org.jetbrains:markdown:$markdown"
|
||||||
|
|
||||||
implementation 'de.charlex.compose:revealswipe:1.0.0'
|
def revealSwipe = "1.0.0"
|
||||||
|
implementation "de.charlex.compose:revealswipe:$revealSwipe"
|
||||||
|
|
||||||
implementation 'com.github.jeziellago:compose-markdown:0.3.3'
|
def compose_markdown = "0.3.3"
|
||||||
|
implementation "com.github.jeziellago:compose-markdown:$compose_markdown"
|
||||||
|
|
||||||
// testing
|
// testing
|
||||||
def junit = "4.13.2"
|
def junit = "4.13.2"
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.owenlejeune.tvtime
|
package com.owenlejeune.tvtime
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.window.OnBackInvokedDispatcher
|
import android.window.OnBackInvokedDispatcher
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
@@ -40,6 +42,14 @@ import org.koin.android.ext.android.inject
|
|||||||
@OptIn(ExperimentalPagerApi::class)
|
@OptIn(ExperimentalPagerApi::class)
|
||||||
class OnboardingActivity: MonetCompatActivity() {
|
class OnboardingActivity: MonetCompatActivity() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun showActivity(sourceActivity: Context) {
|
||||||
|
val intent = Intent(sourceActivity, OnboardingActivity::class.java)
|
||||||
|
// intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
sourceActivity.startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val preferences: AppPreferences by inject()
|
private val preferences: AppPreferences by inject()
|
||||||
|
|
||||||
private lateinit var pagerState: PagerState
|
private lateinit var pagerState: PagerState
|
||||||
@@ -104,53 +114,56 @@ class OnboardingActivity: MonetCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(all = 12.dp)
|
.padding(all = 12.dp)
|
||||||
) {
|
) {
|
||||||
Button(
|
OnboardingPage[pagerState.currentPage].footer.invoke(this@Column)
|
||||||
modifier = Modifier.align(Alignment.CenterStart),
|
Row(
|
||||||
enabled = true,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
onClick = {
|
modifier = Modifier.fillMaxWidth()
|
||||||
preferences.firstLaunch = false
|
|
||||||
launchActivity(MainActivity::class.java)
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
val skipText = if (preferences.firstLaunchTesting)
|
Button(
|
||||||
stringResource(id = R.string.action_skip_testing)
|
enabled = true,
|
||||||
else
|
onClick = {
|
||||||
stringResource(id = R.string.action_skip)
|
|
||||||
Text(text = skipText)
|
|
||||||
}
|
|
||||||
|
|
||||||
HorizontalPagerIndicator(
|
|
||||||
pagerState = pagerState,
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.Center)
|
|
||||||
.padding(16.dp),
|
|
||||||
activeColor = MaterialTheme.colorScheme.secondary
|
|
||||||
)
|
|
||||||
|
|
||||||
Button(
|
|
||||||
modifier = Modifier.align(Alignment.CenterEnd),
|
|
||||||
shape = CircleShape,
|
|
||||||
enabled = nextButtonEnabled.value,
|
|
||||||
onClick = {
|
|
||||||
if (isLastPage) {
|
|
||||||
preferences.firstLaunch = false
|
preferences.firstLaunch = false
|
||||||
launchActivity(MainActivity::class.java)
|
launchActivity(MainActivity::class.java)
|
||||||
} else {
|
}
|
||||||
coroutineScope.launch {
|
) {
|
||||||
pagerState.animateScrollToPage(pagerState.currentPage + 1)
|
val skipText = if (preferences.firstLaunchTesting)
|
||||||
|
stringResource(id = R.string.action_skip_testing)
|
||||||
|
else
|
||||||
|
stringResource(id = R.string.action_skip)
|
||||||
|
Text(text = skipText)
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalPagerIndicator(
|
||||||
|
pagerState = pagerState,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(16.dp),
|
||||||
|
activeColor = MaterialTheme.colorScheme.secondary
|
||||||
|
)
|
||||||
|
|
||||||
|
Button(
|
||||||
|
shape = CircleShape,
|
||||||
|
enabled = nextButtonEnabled.value,
|
||||||
|
onClick = {
|
||||||
|
if (isLastPage) {
|
||||||
|
preferences.firstLaunch = false
|
||||||
|
launchActivity(MainActivity::class.java)
|
||||||
|
} else {
|
||||||
|
coroutineScope.launch {
|
||||||
|
pagerState.animateScrollToPage(pagerState.currentPage + 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
) {
|
||||||
) {
|
if (!isLastPage) {
|
||||||
if (!isLastPage) {
|
Text(stringResource(id = R.string.get_started))
|
||||||
Text(stringResource(id = R.string.get_started))
|
} else {
|
||||||
} else {
|
Icon(imageVector = Icons.Filled.ArrowForward, contentDescription = null)
|
||||||
Icon(imageVector = Icons.Filled.ArrowForward, contentDescription = null)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +198,7 @@ class OnboardingActivity: MonetCompatActivity() {
|
|||||||
color = MaterialTheme.colorScheme.onBackground
|
color = MaterialTheme.colorScheme.onBackground
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(50.dp))
|
Spacer(modifier = Modifier.height(50.dp))
|
||||||
page.additionalContent(this@OnboardingActivity, nextButtonEnabled)
|
page.additionalContent(this@Column, this@OnboardingActivity, nextButtonEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,27 +45,6 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
@OptIn(ExperimentalPagerApi::class)
|
|
||||||
@Composable
|
|
||||||
fun Gallery(
|
|
||||||
pagerState: PagerState,
|
|
||||||
models: List<Any?>,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
contentDescriptions: List<String> = emptyList()
|
|
||||||
) {
|
|
||||||
HorizontalPager(
|
|
||||||
count = models.size,
|
|
||||||
state = pagerState,
|
|
||||||
modifier = modifier
|
|
||||||
) { page ->
|
|
||||||
AsyncImage(
|
|
||||||
model = models[page],
|
|
||||||
contentDescription = contentDescriptions[page],
|
|
||||||
contentScale = ContentScale.FillWidth
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalPagerApi::class)
|
@OptIn(ExperimentalPagerApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun TapGallery(
|
fun TapGallery(
|
||||||
@@ -145,7 +124,7 @@ fun TapGallery(
|
|||||||
imageVector = Icons.Outlined.ChevronLeft,
|
imageVector = Icons.Outlined.ChevronLeft,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
tint = MaterialTheme.colorScheme.surface
|
tint = Color.White
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,114 +139,10 @@ fun TapGallery(
|
|||||||
imageVector = Icons.Outlined.ChevronRight,
|
imageVector = Icons.Outlined.ChevronRight,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
tint = MaterialTheme.colorScheme.surface
|
tint = Color.White
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Box(
|
|
||||||
// modifier = Modifier
|
|
||||||
// .background(brush = leftGradient)
|
|
||||||
// .height(height = sizeImage.value.height.toDp())
|
|
||||||
// .width((sizeImage.value.width/2).toDp())
|
|
||||||
// .align(Alignment.CenterStart)
|
|
||||||
// .onGloballyPositioned { leftSizeImage.value = it.size }
|
|
||||||
// .clickable {
|
|
||||||
// val target =
|
|
||||||
// if (pagerState.currentPage == 0) models.size - 1 else pagerState.currentPage - 1
|
|
||||||
// scope.launch { pagerState.animateScrollToPage(target) }
|
|
||||||
// }
|
|
||||||
// ) {
|
|
||||||
// Icon(
|
|
||||||
// imageVector = Icons.Outlined.ChevronLeft,
|
|
||||||
// contentDescription = null,
|
|
||||||
// modifier = Modifier
|
|
||||||
// .size(48.dp)
|
|
||||||
// .padding(start = 24.dp)
|
|
||||||
// .align(Alignment.CenterStart),
|
|
||||||
// tint = MaterialTheme.colorScheme.surface
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// Box(
|
|
||||||
// modifier = Modifier
|
|
||||||
// .background(brush = rightGradient)
|
|
||||||
// .height(height = sizeImage.value.height.toDp())
|
|
||||||
// .width((sizeImage.value.width/2).toDp())
|
|
||||||
// .align(Alignment.CenterEnd)
|
|
||||||
// .onGloballyPositioned { rightSizeImage.value = it.size }
|
|
||||||
// .clickable {
|
|
||||||
// val target =
|
|
||||||
// if (pagerState.currentPage == models.size - 1) 0 else pagerState.currentPage + 1
|
|
||||||
// scope.launch { pagerState.animateScrollToPage(target) }
|
|
||||||
// }
|
|
||||||
// ) {
|
|
||||||
// Icon(
|
|
||||||
// imageVector = Icons.Outlined.ChevronRight,
|
|
||||||
// contentDescription = null,
|
|
||||||
// modifier = Modifier
|
|
||||||
// .size(48.dp)
|
|
||||||
// .padding(end = 24.dp)
|
|
||||||
// .align(Alignment.CenterEnd),
|
|
||||||
// tint = MaterialTheme.colorScheme.surface
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnimatedVisibility(
|
|
||||||
// visible = showControls.value,
|
|
||||||
// enter = fadeIn(),
|
|
||||||
// exit = fadeOut()
|
|
||||||
// ) {
|
|
||||||
// val leftSizeImage = remember { mutableStateOf(IntSize.Zero) }
|
|
||||||
// val leftGradient = Brush.horizontalGradient(
|
|
||||||
// colors = listOf(Color.Black, Color.Transparent),
|
|
||||||
// startX = 0f,
|
|
||||||
// endX = leftSizeImage.value.width.toFloat()
|
|
||||||
// )
|
|
||||||
// Box(
|
|
||||||
// modifier = Modifier
|
|
||||||
// .background(brush = leftGradient)
|
|
||||||
// .fillMaxHeight()
|
|
||||||
// .width(100.dp)
|
|
||||||
// .align(Alignment.CenterStart)
|
|
||||||
// .onGloballyPositioned { leftSizeImage.value = it.size }
|
|
||||||
// .clickable {
|
|
||||||
// val target =
|
|
||||||
// if (pagerState.currentPage == 0) models.size - 1 else pagerState.currentPage + 1
|
|
||||||
// scope.launch { pagerState.animateScrollToPage(target) }
|
|
||||||
// }
|
|
||||||
// ) {
|
|
||||||
// Icon(
|
|
||||||
// imageVector = Icons.Outlined.ChevronLeft,
|
|
||||||
// contentDescription = null,
|
|
||||||
// modifier = Modifier.size(48.dp)
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// val rightSizeImage = remember { mutableStateOf(IntSize.Zero) }
|
|
||||||
// val rightGradient = Brush.horizontalGradient(
|
|
||||||
// colors = listOf(Color.Black, Color.Transparent),
|
|
||||||
// startX = leftSizeImage.value.width.toFloat(),
|
|
||||||
// endX = 0f
|
|
||||||
// )
|
|
||||||
// Box(
|
|
||||||
// modifier = Modifier
|
|
||||||
// .background(brush = rightGradient)
|
|
||||||
// .fillMaxHeight()
|
|
||||||
// .width(100.dp)
|
|
||||||
// .align(Alignment.CenterEnd)
|
|
||||||
// .onGloballyPositioned { rightSizeImage.value = it.size }
|
|
||||||
// .clickable {
|
|
||||||
// val target =
|
|
||||||
// if (pagerState.currentPage == models.size - 1) 0 else pagerState.currentPage - 1
|
|
||||||
// scope.launch { pagerState.animateScrollToPage(target) }
|
|
||||||
// }
|
|
||||||
// ) {
|
|
||||||
// Icon(
|
|
||||||
// imageVector = Icons.Outlined.ChevronRight,
|
|
||||||
// contentDescription = null,
|
|
||||||
// modifier = Modifier.size(48.dp)
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,9 @@ import androidx.compose.foundation.layout.RowScope
|
|||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Info
|
import androidx.compose.material.icons.outlined.Info
|
||||||
import androidx.compose.material.icons.outlined.Login
|
import androidx.compose.material.icons.outlined.Login
|
||||||
@@ -30,9 +32,11 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
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.compositeOver
|
import androidx.compose.ui.graphics.compositeOver
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
@@ -213,12 +217,27 @@ fun ProfileMenuOverlay(
|
|||||||
|
|
||||||
MenuDivider()
|
MenuDivider()
|
||||||
|
|
||||||
Text(
|
Row(
|
||||||
text = "${stringResource(id = R.string.app_name)} v${BuildConfig.VERSION_NAME}",
|
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||||
fontSize = 10.sp,
|
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||||
textAlign = TextAlign.Center,
|
verticalAlignment = Alignment.CenterVertically
|
||||||
modifier = Modifier.fillMaxWidth()
|
) {
|
||||||
)
|
Text(
|
||||||
|
text = "${stringResource(id = R.string.app_name)} v${BuildConfig.VERSION_NAME}",
|
||||||
|
fontSize = 10.sp
|
||||||
|
)
|
||||||
|
Text(text = "•")
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.tmdb_logo),
|
||||||
|
tint = Color.Unspecified,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(16.dp)
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.powered_by_tmdb),
|
||||||
|
fontSize = 10.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,6 +256,8 @@ private fun ProfileMenuItem(
|
|||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.clip(RoundedCornerShape(10.dp))
|
||||||
|
.padding(horizontal = 4.dp)
|
||||||
.clickable(
|
.clickable(
|
||||||
enabled = onClick != null,
|
enabled = onClick != null,
|
||||||
onClick = onClick ?: {}
|
onClick = onClick ?: {}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.owenlejeune.tvtime.R
|
import com.owenlejeune.tvtime.R
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.DetailService
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.DetailService
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.MoviesService
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.MoviesService
|
||||||
@@ -47,6 +48,10 @@ fun SearchScreen(
|
|||||||
title: String,
|
title: String,
|
||||||
mediaViewType: MediaViewType
|
mediaViewType: MediaViewType
|
||||||
) {
|
) {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
systemUiController.setNavigationBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
|
|||||||
@@ -8,10 +8,16 @@ import androidx.compose.foundation.clickable
|
|||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.layout.wrapContentHeight
|
import androidx.compose.foundation.layout.wrapContentHeight
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.outlined.Description
|
import androidx.compose.material.icons.outlined.Description
|
||||||
@@ -34,13 +40,17 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
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.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
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.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.owenlejeune.tvtime.BuildConfig
|
import com.owenlejeune.tvtime.BuildConfig
|
||||||
import com.owenlejeune.tvtime.R
|
import com.owenlejeune.tvtime.R
|
||||||
import com.owenlejeune.tvtime.utils.FileUtils
|
import com.owenlejeune.tvtime.utils.FileUtils
|
||||||
@@ -51,6 +61,10 @@ import dev.jeziellago.compose.markdowntext.MarkdownText
|
|||||||
fun AboutView(
|
fun AboutView(
|
||||||
appNavController: NavController
|
appNavController: NavController
|
||||||
) {
|
) {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
systemUiController.setNavigationBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
val decayAnimationSpec = rememberSplineBasedDecay<Float>()
|
val decayAnimationSpec = rememberSplineBasedDecay<Float>()
|
||||||
@@ -78,11 +92,10 @@ fun AboutView(
|
|||||||
) {
|
) {
|
||||||
Box(modifier = Modifier.padding(it)) {
|
Box(modifier = Modifier.padding(it)) {
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(24.dp),
|
modifier = Modifier.padding(horizontal = 12.dp)
|
||||||
modifier = Modifier.padding(horizontal = 24.dp)
|
|
||||||
) {
|
) {
|
||||||
AboutItem(
|
AboutItem(
|
||||||
title = "App Info",
|
title = stringResource(R.string.app_info_label),
|
||||||
subtitle = "v${BuildConfig.VERSION_NAME}",
|
subtitle = "v${BuildConfig.VERSION_NAME}",
|
||||||
icon = Icons.Outlined.Info,
|
icon = Icons.Outlined.Info,
|
||||||
onClick = {
|
onClick = {
|
||||||
@@ -96,7 +109,7 @@ fun AboutView(
|
|||||||
|
|
||||||
var showChangeLog by remember { mutableStateOf(false) }
|
var showChangeLog by remember { mutableStateOf(false) }
|
||||||
AboutItem(
|
AboutItem(
|
||||||
title = "Changelog",
|
title = stringResource(R.string.changelog_label),
|
||||||
icon = Icons.Outlined.Description,
|
icon = Icons.Outlined.Description,
|
||||||
onClick = { showChangeLog = true }
|
onClick = { showChangeLog = true }
|
||||||
)
|
)
|
||||||
@@ -104,6 +117,18 @@ fun AboutView(
|
|||||||
visible = showChangeLog,
|
visible = showChangeLog,
|
||||||
onDismissRequest = { showChangeLog = false }
|
onDismissRequest = { showChangeLog = false }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
AboutItem(
|
||||||
|
title = "Privacy Policy",
|
||||||
|
onClick = {}
|
||||||
|
)
|
||||||
|
|
||||||
|
AboutItem(
|
||||||
|
title = "Terms of Use",
|
||||||
|
onClick = {}
|
||||||
|
)
|
||||||
|
|
||||||
|
AttributionSection()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,29 +138,34 @@ fun AboutView(
|
|||||||
private fun AboutItem(
|
private fun AboutItem(
|
||||||
title: String,
|
title: String,
|
||||||
subtitle: String? = null,
|
subtitle: String? = null,
|
||||||
icon: ImageVector,
|
icon: ImageVector? = null,
|
||||||
onClick: (() -> Unit)? = null
|
onClick: (() -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.wrapContentHeight()
|
.wrapContentHeight()
|
||||||
|
.clip(RoundedCornerShape(10.dp))
|
||||||
.clickable(
|
.clickable(
|
||||||
onClick = onClick ?: {},
|
onClick = onClick ?: {},
|
||||||
enabled = onClick != null
|
enabled = onClick != null
|
||||||
),
|
)
|
||||||
horizontalArrangement = Arrangement.spacedBy(24.dp)
|
|
||||||
) {
|
) {
|
||||||
Icon(
|
icon?.let {
|
||||||
imageVector = icon,
|
Icon(
|
||||||
contentDescription = subtitle,
|
imageVector = icon,
|
||||||
modifier = Modifier.align(Alignment.CenterVertically),
|
contentDescription = subtitle,
|
||||||
tint = MaterialTheme.colorScheme.primary
|
modifier = Modifier
|
||||||
)
|
.align(Alignment.CenterVertically)
|
||||||
|
.padding(all = 12.dp),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
}
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.CenterVertically)
|
.align(Alignment.CenterVertically)
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
|
.padding(all = 12.dp)
|
||||||
) {
|
) {
|
||||||
val titleColor = MaterialTheme.colorScheme.onBackground
|
val titleColor = MaterialTheme.colorScheme.onBackground
|
||||||
val subtitleColor = MaterialTheme.colorScheme.onSurfaceVariant
|
val subtitleColor = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
@@ -161,12 +191,54 @@ private fun ChangeLogDialog(
|
|||||||
Button(
|
Button(
|
||||||
onClick = onDismissRequest
|
onClick = onDismissRequest
|
||||||
) {
|
) {
|
||||||
Text(text = "Close")
|
Text(text = stringResource(id = R.string.action_dismiss))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
text = {
|
text = {
|
||||||
MarkdownText(markdown = changeLog)
|
MarkdownText(
|
||||||
|
markdown = changeLog,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ColumnScope.AttributionSection() {
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.wrapContentHeight()
|
||||||
|
.clip(RoundedCornerShape(10.dp))
|
||||||
|
.clickable(
|
||||||
|
onClick = {
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(context.getString(R.string.tmdb_home_page)))
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.tmdb_logo),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
tint = Color.Unspecified
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = R.string.attribution_text),
|
||||||
|
fontSize = 12.sp
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.width(12.dp))
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,9 +8,11 @@ import androidx.compose.material.icons.filled.ArrowBack
|
|||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
@@ -24,6 +26,7 @@ import com.google.accompanist.pager.ExperimentalPagerApi
|
|||||||
import com.google.accompanist.pager.HorizontalPager
|
import com.google.accompanist.pager.HorizontalPager
|
||||||
import com.google.accompanist.pager.PagerState
|
import com.google.accompanist.pager.PagerState
|
||||||
import com.google.accompanist.pager.rememberPagerState
|
import com.google.accompanist.pager.rememberPagerState
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.owenlejeune.tvtime.R
|
import com.owenlejeune.tvtime.R
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.*
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.*
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4AccountList
|
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4AccountList
|
||||||
@@ -48,59 +51,67 @@ fun AccountView(
|
|||||||
appNavController: NavHostController,
|
appNavController: NavHostController,
|
||||||
doSignInPartTwo: Boolean = false
|
doSignInPartTwo: Boolean = false
|
||||||
) {
|
) {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
systemUiController.setNavigationBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
|
||||||
val currentSessionState = remember { SessionManager.currentSession }
|
val currentSessionState = remember { SessionManager.currentSession }
|
||||||
val currentSession = currentSessionState.value
|
val currentSession = currentSessionState.value
|
||||||
|
|
||||||
val showProfileMenuOverlay = remember { mutableStateOf(false) }
|
val decayAnimationSpec = rememberSplineBasedDecay<Float>()
|
||||||
|
val topAppBarScrollState = rememberTopAppBarScrollState()
|
||||||
ProfileMenuContainer(
|
val scrollBehavior = remember(decayAnimationSpec) {
|
||||||
appNavController = appNavController,
|
TopAppBarDefaults.exitUntilCollapsedScrollBehavior(decayAnimationSpec, topAppBarScrollState)
|
||||||
visible = showProfileMenuOverlay.value,
|
}
|
||||||
onDismissRequest = { showProfileMenuOverlay.value = false }
|
Scaffold(
|
||||||
) {
|
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
val decayAnimationSpec = rememberSplineBasedDecay<Float>()
|
topBar = {
|
||||||
val topAppBarScrollState = rememberTopAppBarScrollState()
|
LargeTopAppBar(
|
||||||
val scrollBehavior = remember(decayAnimationSpec) {
|
scrollBehavior = scrollBehavior,
|
||||||
TopAppBarDefaults.exitUntilCollapsedScrollBehavior(decayAnimationSpec, topAppBarScrollState)
|
navigationIcon = {
|
||||||
}
|
IconButton(
|
||||||
Scaffold(
|
onClick = { appNavController.popBackStack() }
|
||||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
) {
|
||||||
topBar = {
|
Icon(
|
||||||
LargeTopAppBar(
|
Icons.Filled.ArrowBack,
|
||||||
scrollBehavior = scrollBehavior,
|
contentDescription = null
|
||||||
navigationIcon = {
|
|
||||||
IconButton(
|
|
||||||
onClick = { appNavController.popBackStack() }
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
Icons.Filled.ArrowBack,
|
|
||||||
contentDescription = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
title = {
|
|
||||||
if (currentSession?.isAuthorized == false) {
|
|
||||||
Text(text = stringResource(id = R.string.account_not_logged_in))
|
|
||||||
} else {
|
|
||||||
val accountDetails = remember { currentSession!!.accountDetails }
|
|
||||||
Text(text = getAccountName(accountDetails.value))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
colors = TopAppBarDefaults.largeTopAppBarColors(scrolledContainerColor = MaterialTheme.colorScheme.background),
|
|
||||||
actions = {
|
|
||||||
AccountIcon(
|
|
||||||
modifier = Modifier.padding(start = 12.dp),
|
|
||||||
size = 32.dp,
|
|
||||||
onClick = { showProfileMenuOverlay.value = true }
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(8.dp))
|
|
||||||
}
|
}
|
||||||
)
|
},
|
||||||
}
|
title = {
|
||||||
) {
|
if (currentSession?.isAuthorized == false) {
|
||||||
Box(modifier = Modifier.padding(it)) {
|
Text(text = stringResource(id = R.string.account_not_logged_in))
|
||||||
AccountViewContent(appNavController = appNavController, doSignInPartTwo = doSignInPartTwo)
|
} else {
|
||||||
}
|
val accountDetails = remember { currentSession!!.accountDetails }
|
||||||
|
Text(text = getAccountName(accountDetails.value))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = TopAppBarDefaults.largeTopAppBarColors(scrolledContainerColor = MaterialTheme.colorScheme.background),
|
||||||
|
actions = {
|
||||||
|
var showDropDownMenu by remember { mutableStateOf(false) }
|
||||||
|
AccountIcon(
|
||||||
|
modifier = Modifier.padding(end = 8.dp),
|
||||||
|
size = 32.dp,
|
||||||
|
onClick = { showDropDownMenu = true }
|
||||||
|
)
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = showDropDownMenu,
|
||||||
|
onDismissRequest = { showDropDownMenu = false}
|
||||||
|
) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(text = stringResource(id = R.string.action_sign_out)) },
|
||||||
|
onClick = {
|
||||||
|
SessionManager.clearSession()
|
||||||
|
appNavController.popBackStack()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Box(modifier = Modifier.padding(it)) {
|
||||||
|
AccountViewContent(appNavController = appNavController, doSignInPartTwo = doSignInPartTwo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import androidx.constraintlayout.compose.ConstraintLayout
|
|||||||
import androidx.constraintlayout.compose.Dimension
|
import androidx.constraintlayout.compose.Dimension
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.owenlejeune.tvtime.R
|
import com.owenlejeune.tvtime.R
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.AccountService
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.AccountService
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.MarkAsFavoriteBody
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.MarkAsFavoriteBody
|
||||||
@@ -65,6 +66,10 @@ fun ListDetailView(
|
|||||||
windowSize: WindowSizeClass,
|
windowSize: WindowSizeClass,
|
||||||
preferences: AppPreferences = KoinJavaComponent.get(AppPreferences::class.java)
|
preferences: AppPreferences = KoinJavaComponent.get(AppPreferences::class.java)
|
||||||
) {
|
) {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
systemUiController.setNavigationBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
|
||||||
val service = ListV4Service()
|
val service = ListV4Service()
|
||||||
|
|
||||||
val parentList = remember { mutableStateOf<MediaList?>(null) }
|
val parentList = remember { mutableStateOf<MediaList?>(null) }
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import com.google.accompanist.flowlayout.FlowRow
|
|||||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||||
import com.google.accompanist.pager.PagerState
|
import com.google.accompanist.pager.PagerState
|
||||||
import com.google.accompanist.pager.rememberPagerState
|
import com.google.accompanist.pager.rememberPagerState
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.owenlejeune.tvtime.R
|
import com.owenlejeune.tvtime.R
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.AccountService
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.AccountService
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.DetailService
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.DetailService
|
||||||
@@ -69,6 +70,10 @@ fun MediaDetailView(
|
|||||||
windowSize: WindowSizeClass,
|
windowSize: WindowSizeClass,
|
||||||
preferences: AppPreferences = get(AppPreferences::class.java)
|
preferences: AppPreferences = get(AppPreferences::class.java)
|
||||||
) {
|
) {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
systemUiController.setNavigationBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
|
||||||
val service = when (type) {
|
val service = when (type) {
|
||||||
MediaViewType.MOVIE -> MoviesService()
|
MediaViewType.MOVIE -> MoviesService()
|
||||||
MediaViewType.TV -> TvService()
|
MediaViewType.TV -> TvService()
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
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.api.tmdb.api.v3.model.DetailPerson
|
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailPerson
|
||||||
@@ -40,6 +41,10 @@ fun PersonDetailView(
|
|||||||
appNavController: NavController,
|
appNavController: NavController,
|
||||||
personId: Int?
|
personId: Int?
|
||||||
) {
|
) {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
systemUiController.setNavigationBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
|
||||||
val person = remember { mutableStateOf<DetailPerson?>(null) }
|
val person = remember { mutableStateOf<DetailPerson?>(null) }
|
||||||
personId?.let {
|
personId?.let {
|
||||||
if (person.value == null) {
|
if (person.value == null) {
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ import androidx.navigation.NavController
|
|||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.kieronquinn.monetcompat.core.MonetCompat
|
import com.kieronquinn.monetcompat.core.MonetCompat
|
||||||
import com.owenlejeune.tvtime.BuildConfig
|
import com.owenlejeune.tvtime.BuildConfig
|
||||||
|
import com.owenlejeune.tvtime.OnboardingActivity
|
||||||
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.*
|
||||||
@@ -53,6 +55,10 @@ fun SettingsTab(
|
|||||||
route: String? = null,
|
route: String? = null,
|
||||||
preferences: AppPreferences = get(AppPreferences::class.java)
|
preferences: AppPreferences = get(AppPreferences::class.java)
|
||||||
) {
|
) {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
systemUiController.setNavigationBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
|
||||||
val decayAnimationSpec = rememberSplineBasedDecay<Float>()
|
val decayAnimationSpec = rememberSplineBasedDecay<Float>()
|
||||||
val topAppBarScrollState = rememberTopAppBarScrollState()
|
val topAppBarScrollState = rememberTopAppBarScrollState()
|
||||||
val scrollBehavior = remember(decayAnimationSpec) {
|
val scrollBehavior = remember(decayAnimationSpec) {
|
||||||
@@ -445,6 +451,15 @@ private fun DevPreferences(
|
|||||||
preferences.firstLaunchTesting = isChecked
|
preferences.firstLaunchTesting = isChecked
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
Text(
|
||||||
|
text = "Show onboarding UI",
|
||||||
|
color = MaterialTheme.colorScheme.onBackground,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 8.dp, vertical = 12.dp)
|
||||||
|
.clickable {
|
||||||
|
OnboardingActivity.showActivity(context)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
val shouldShowPalette = remember { mutableStateOf(false) }
|
val shouldShowPalette = remember { mutableStateOf(false) }
|
||||||
Text(
|
Text(
|
||||||
|
|||||||
@@ -14,11 +14,13 @@ import androidx.compose.material.icons.filled.Close
|
|||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.SmallTopAppBar
|
import androidx.compose.material3.SmallTopAppBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
import com.google.accompanist.web.AccompanistWebViewClient
|
import com.google.accompanist.web.AccompanistWebViewClient
|
||||||
import com.google.accompanist.web.WebView
|
import com.google.accompanist.web.WebView
|
||||||
import com.google.accompanist.web.rememberWebViewState
|
import com.google.accompanist.web.rememberWebViewState
|
||||||
@@ -32,6 +34,10 @@ fun WebLinkView(
|
|||||||
url: String,
|
url: String,
|
||||||
appNavController: NavController
|
appNavController: NavController
|
||||||
) {
|
) {
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
systemUiController.setStatusBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
systemUiController.setNavigationBarColor(color = MaterialTheme.colorScheme.background)
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
SmallTopAppBar(
|
SmallTopAppBar(
|
||||||
|
|||||||
@@ -4,8 +4,16 @@ import android.os.Build
|
|||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Brightness6
|
import androidx.compose.material.icons.filled.Brightness6
|
||||||
import androidx.compose.material.icons.filled.Search
|
import androidx.compose.material.icons.filled.Search
|
||||||
@@ -13,13 +21,19 @@ 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.FloatingActionButton
|
import androidx.compose.material3.FloatingActionButton
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
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.preferences.AppPreferences
|
import com.owenlejeune.tvtime.preferences.AppPreferences
|
||||||
@@ -34,7 +48,8 @@ sealed class OnboardingPage(
|
|||||||
@StringRes val title: Int,
|
@StringRes val title: Int,
|
||||||
@StringRes val description: Int,
|
@StringRes val description: Int,
|
||||||
@DrawableRes val image: Int? = null,
|
@DrawableRes val image: Int? = null,
|
||||||
val additionalContent: @Composable (AppCompatActivity, MutableState<Boolean>) -> Unit = { a, e -> }
|
val additionalContent: @Composable ColumnScope.(AppCompatActivity, MutableState<Boolean>) -> Unit = { _, _ -> },
|
||||||
|
val footer: @Composable ColumnScope.() -> Unit = {}
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object: KoinComponent {
|
companion object: KoinComponent {
|
||||||
@@ -49,7 +64,29 @@ sealed class OnboardingPage(
|
|||||||
order = 0,
|
order = 0,
|
||||||
title = R.string.app_name,
|
title = R.string.app_name,
|
||||||
description = R.string.intro_page_desc,
|
description = R.string.intro_page_desc,
|
||||||
image = R.drawable.ic_launcher_foreground
|
image = R.drawable.ic_launcher_foreground,
|
||||||
|
footer = {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.CenterHorizontally)
|
||||||
|
.wrapContentWidth()
|
||||||
|
.padding(all = 24.dp)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.tmdb_logo),
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(32.dp),
|
||||||
|
tint = Color.Unspecified
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = R.string.attribution_text),
|
||||||
|
fontSize = 12.sp,
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
object SignInPage: OnboardingPage(
|
object SignInPage: OnboardingPage(
|
||||||
|
|||||||
22
app/src/main/res/drawable/tmdb_logo.xml
Normal file
22
app/src/main/res/drawable/tmdb_logo.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="185.04dp"
|
||||||
|
android:height="133.4dp"
|
||||||
|
android:viewportWidth="185.04"
|
||||||
|
android:viewportHeight="133.4">
|
||||||
|
<path
|
||||||
|
android:pathData="M51.06,66.7h0A17.67,17.67 0,0 1,68.73 49h-0.1A17.67,17.67 0,0 1,86.3 66.7h0A17.67,17.67 0,0 1,68.63 84.37h0.1A17.67,17.67 0,0 1,51.06 66.7ZM133.73,35.37h32.9A17.67,17.67 0,0 0,184.3 17.7h0A17.67,17.67 0,0 0,166.63 0h-32.9A17.67,17.67 0,0 0,116.06 17.7h0A17.67,17.67 0,0 0,133.73 35.37ZM20.73,133.37h63.9A17.67,17.67 0,0 0,102.3 115.7h0A17.67,17.67 0,0 0,84.63 98L20.73,98A17.67,17.67 0,0 0,3.06 115.7h0A17.67,17.67 0,0 0,20.73 133.37ZM104.65,84.37h6.25L125.5,49h-8.35l-8.9,23.2h-0.1L99.4,49L90.5,49ZM137.1,84.37h7.8L144.9,49h-7.8ZM159.3,84.37h24.95L184.25,77.2L167.1,77.2L167.1,70h15.35L182.45,62.8L167.1,62.8L167.1,56.2h16.25L183.35,49h-24ZM10.1,35.4h7.8L17.9,6.9L28,6.9L28,0L0,0L0,6.9L10.1,6.9ZM39,35.4h7.8L46.8,20.1L61.9,20.1L61.9,35.4h7.8L69.7,0L61.9,0L61.9,13.2L46.75,13.2L46.75,0L39,0ZM80.25,35.4h25L105.25,28.2L88,28.2L88,21h15.35L103.35,13.8L88,13.8L88,7.2h16.25L104.25,0h-24ZM1.25,84.4L9,84.4L9,57.25h0.1l9,27.15L24,84.4l9.3,-27.15h0.1L33.4,84.4h7.8L41.2,49L29.45,49l-8.2,23.1h-0.1L13,49L1.2,49ZM113.34,133.4L126,133.4a24.59,24.59 0,0 0,7.56 -1.15,19.52 19.52,0 0,0 6.35,-3.37 16.37,16.37 0,0 0,4.37 -5.5A16.91,16.91 0,0 0,146 115.8a18.5,18.5 0,0 0,-1.68 -8.25,15.1 15.1,0 0,0 -4.52,-5.53A18.55,18.55 0,0 0,133.07 99,33.54 33.54,0 0,0 125,98L113.29,98ZM121.15,105.2h4.6a17.43,17.43 0,0 1,4.67 0.62,11.68 11.68,0 0,1 3.88,1.88 9,9 0,0 1,2.62 3.18,9.87 9.87,0 0,1 1,4.52 11.92,11.92 0,0 1,-1 5.08,8.69 8.69,0 0,1 -2.67,3.34 10.87,10.87 0,0 1,-4 1.83,21.57 21.57,0 0,1 -5,0.55L121.1,126.2ZM157.29,133.4h14.5a23.11,23.11 0,0 0,4.73 -0.5,13.38 13.38,0 0,0 4.27,-1.65 9.42,9.42 0,0 0,3.1 -3,8.52 8.52,0 0,0 1.2,-4.68 9.16,9.16 0,0 0,-0.55 -3.2,7.79 7.79,0 0,0 -1.57,-2.62 8.38,8.38 0,0 0,-2.45 -1.85,10 10,0 0,0 -3.18,-1v-0.1a9.28,9.28 0,0 0,4.43 -2.82,7.42 7.42,0 0,0 1.67,-5 8.34,8.34 0,0 0,-1.15 -4.65,7.88 7.88,0 0,0 -3,-2.73 12.9,12.9 0,0 0,-4.17 -1.3,34.42 34.42,0 0,0 -4.63,-0.32h-13.2ZM165.09,104.6h5.3a10.79,10.79 0,0 1,1.85 0.17,5.77 5.77,0 0,1 1.7,0.58 3.33,3.33 0,0 1,1.23 1.13,3.22 3.22,0 0,1 0.47,1.82 3.63,3.63 0,0 1,-0.42 1.8,3.34 3.34,0 0,1 -1.13,1.2 4.78,4.78 0,0 1,-1.57 0.65,8.16 8.16,0 0,1 -1.78,0.2L165,112.15ZM165.09,118.75h5.9a15.12,15.12 0,0 1,2.05 0.15,7.83 7.83,0 0,1 2,0.55 4,4 0,0 1,1.58 1.17,3.13 3.13,0 0,1 0.62,2 3.71,3.71 0,0 1,-0.47 1.95,4 4,0 0,1 -1.23,1.3 4.78,4.78 0,0 1,-1.67 0.7,8.91 8.91,0 0,1 -1.83,0.2h-7Z">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:startX="0"
|
||||||
|
android:startY="66.7"
|
||||||
|
android:endX="185.04"
|
||||||
|
android:endY="66.7"
|
||||||
|
android:type="linear">
|
||||||
|
<item android:offset="0" android:color="#FF90CEA1"/>
|
||||||
|
<item android:offset="0.56" android:color="#FF3CBEC9"/>
|
||||||
|
<item android:offset="1" android:color="#FF00B3E5"/>
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
</vector>
|
||||||
@@ -215,4 +215,10 @@
|
|||||||
<string name="recommended_tv_title">Recommended TV</string>
|
<string name="recommended_tv_title">Recommended TV</string>
|
||||||
<string name="no_recommended_tv">No Recommended TV</string>
|
<string name="no_recommended_tv">No Recommended TV</string>
|
||||||
<string name="no_result_found">No more results found</string>
|
<string name="no_result_found">No more results found</string>
|
||||||
|
|
||||||
|
<string name="attribution_text">This product uses the TMDB API but is not endorsed or certified by TMDB.</string>
|
||||||
|
<string name="tmdb_home_page">"https://www.themoviedb.org"</string>
|
||||||
|
<string name="app_info_label">App Info</string>
|
||||||
|
<string name="changelog_label">Changelog</string>
|
||||||
|
<string name="powered_by_tmdb">Powered by TMDB</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user