Migrate More screen to full Compose

This commit is contained in:
arkon 2022-07-18 18:51:36 -04:00
parent e2510c144a
commit 4d9d587366
6 changed files with 105 additions and 122 deletions

View file

@ -3,6 +3,7 @@ package eu.kanade.presentation.more
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.CloudOff import androidx.compose.material.icons.outlined.CloudOff
import androidx.compose.material.icons.outlined.GetApp import androidx.compose.material.icons.outlined.GetApp
@ -16,15 +17,16 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.Divider import eu.kanade.presentation.components.Divider
import eu.kanade.presentation.components.PreferenceRow import eu.kanade.presentation.components.PreferenceRow
import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.components.ScrollbarLazyColumn import eu.kanade.presentation.components.ScrollbarLazyColumn
import eu.kanade.presentation.components.SwitchPreference import eu.kanade.presentation.components.SwitchPreference
import eu.kanade.presentation.util.plus
import eu.kanade.presentation.util.quantityStringResource import eu.kanade.presentation.util.quantityStringResource
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.more.DownloadQueueState import eu.kanade.tachiyomi.ui.more.DownloadQueueState
@ -33,7 +35,6 @@ import eu.kanade.tachiyomi.ui.more.MorePresenter
@Composable @Composable
fun MoreScreen( fun MoreScreen(
nestedScrollInterop: NestedScrollConnection,
presenter: MorePresenter, presenter: MorePresenter,
onClickDownloadQueue: () -> Unit, onClickDownloadQueue: () -> Unit,
onClickCategories: () -> Unit, onClickCategories: () -> Unit,
@ -44,92 +45,108 @@ fun MoreScreen(
val uriHandler = LocalUriHandler.current val uriHandler = LocalUriHandler.current
val downloadQueueState by presenter.downloadQueueState.collectAsState() val downloadQueueState by presenter.downloadQueueState.collectAsState()
ScrollbarLazyColumn( Scaffold(
modifier = Modifier.nestedScroll(nestedScrollInterop), modifier = Modifier.statusBarsPadding(),
contentPadding = WindowInsets.navigationBars.asPaddingValues(), topBar = {
) { AppBar(
item { title = stringResource(R.string.label_more),
LogoHeader() downloadedOnlyMode = presenter.downloadedOnly.value,
} incognitoMode = presenter.incognitoMode.value,
item {
SwitchPreference(
preference = presenter.downloadedOnly,
title = stringResource(R.string.label_downloaded_only),
subtitle = stringResource(R.string.downloaded_only_summary),
painter = rememberVectorPainter(Icons.Outlined.CloudOff),
) )
} },
item { ) { paddingValues ->
SwitchPreference( ScrollbarLazyColumn(
preference = presenter.incognitoMode, contentPadding = paddingValues + WindowInsets.navigationBars.asPaddingValues(),
title = stringResource(R.string.pref_incognito_mode), ) {
subtitle = stringResource(R.string.pref_incognito_mode_summary), item {
painter = painterResource(R.drawable.ic_glasses_24dp), LogoHeader()
) }
}
item { Divider() } item {
SwitchPreference(
preference = presenter.downloadedOnly,
title = stringResource(R.string.label_downloaded_only),
subtitle = stringResource(R.string.downloaded_only_summary),
painter = rememberVectorPainter(Icons.Outlined.CloudOff),
)
}
item {
SwitchPreference(
preference = presenter.incognitoMode,
title = stringResource(R.string.pref_incognito_mode),
subtitle = stringResource(R.string.pref_incognito_mode_summary),
painter = painterResource(R.drawable.ic_glasses_24dp),
)
}
item { item { Divider() }
PreferenceRow(
title = stringResource(R.string.label_download_queue), item {
subtitle = when (downloadQueueState) { PreferenceRow(
DownloadQueueState.Stopped -> null title = stringResource(R.string.label_download_queue),
is DownloadQueueState.Paused -> { subtitle = when (downloadQueueState) {
val pending = (downloadQueueState as DownloadQueueState.Paused).pending DownloadQueueState.Stopped -> null
if (pending == 0) { is DownloadQueueState.Paused -> {
stringResource(R.string.paused) val pending = (downloadQueueState as DownloadQueueState.Paused).pending
} else { if (pending == 0) {
"${stringResource(R.string.paused)}${quantityStringResource(R.plurals.download_queue_summary, pending, pending)}" stringResource(R.string.paused)
} else {
"${stringResource(R.string.paused)}${
quantityStringResource(
R.plurals.download_queue_summary,
pending,
pending,
)
}"
}
} }
} is DownloadQueueState.Downloading -> {
is DownloadQueueState.Downloading -> { val pending = (downloadQueueState as DownloadQueueState.Downloading).pending
val pending = (downloadQueueState as DownloadQueueState.Downloading).pending quantityStringResource(R.plurals.download_queue_summary, pending, pending)
quantityStringResource(R.plurals.download_queue_summary, pending, pending) }
} },
}, painter = rememberVectorPainter(Icons.Outlined.GetApp),
painter = rememberVectorPainter(Icons.Outlined.GetApp), onClick = onClickDownloadQueue,
onClick = onClickDownloadQueue, )
) }
} item {
item { PreferenceRow(
PreferenceRow( title = stringResource(R.string.categories),
title = stringResource(R.string.categories), painter = rememberVectorPainter(Icons.Outlined.Label),
painter = rememberVectorPainter(Icons.Outlined.Label), onClick = onClickCategories,
onClick = onClickCategories, )
) }
} item {
item { PreferenceRow(
PreferenceRow( title = stringResource(R.string.label_backup),
title = stringResource(R.string.label_backup), painter = rememberVectorPainter(Icons.Outlined.SettingsBackupRestore),
painter = rememberVectorPainter(Icons.Outlined.SettingsBackupRestore), onClick = onClickBackupAndRestore,
onClick = onClickBackupAndRestore, )
) }
}
item { Divider() } item { Divider() }
item { item {
PreferenceRow( PreferenceRow(
title = stringResource(R.string.label_settings), title = stringResource(R.string.label_settings),
painter = rememberVectorPainter(Icons.Outlined.Settings), painter = rememberVectorPainter(Icons.Outlined.Settings),
onClick = onClickSettings, onClick = onClickSettings,
) )
} }
item { item {
PreferenceRow( PreferenceRow(
title = stringResource(R.string.pref_category_about), title = stringResource(R.string.pref_category_about),
painter = rememberVectorPainter(Icons.Outlined.Info), painter = rememberVectorPainter(Icons.Outlined.Info),
onClick = onClickAbout, onClick = onClickAbout,
) )
} }
item { item {
PreferenceRow( PreferenceRow(
title = stringResource(R.string.label_help), title = stringResource(R.string.label_help),
painter = rememberVectorPainter(Icons.Outlined.HelpOutline), painter = rememberVectorPainter(Icons.Outlined.HelpOutline),
onClick = { uriHandler.openUri(MoreController.URL_HELP) }, onClick = { uriHandler.openUri(MoreController.URL_HELP) },
) )
}
} }
} }
} }

View file

@ -6,7 +6,6 @@ import androidx.core.net.toUri
import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.Router import com.bluelinelabs.conductor.Router
import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.RouterTransaction
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.util.system.openInBrowser import eu.kanade.tachiyomi.util.system.openInBrowser
fun Router.setRoot(controller: Controller, id: Int) { fun Router.setRoot(controller: Controller, id: Int) {
@ -44,10 +43,3 @@ fun Controller.withFadeTransaction(): RouterTransaction {
fun Controller.openInBrowser(url: String) { fun Controller.openInBrowser(url: String) {
activity?.openInBrowser(url.toUri()) activity?.openInBrowser(url.toUri())
} }
/**
* Returns [MainActivity]'s app bar height
*/
fun Controller.getMainAppBarHeight(): Int {
return (activity as? MainActivity)?.binding?.appbar?.measuredHeight ?: 0
}

View file

@ -1,3 +0,0 @@
package eu.kanade.tachiyomi.ui.base.controller
interface NoAppBarElevationController

View file

@ -44,7 +44,6 @@ import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.FabController import eu.kanade.tachiyomi.ui.base.controller.FabController
import eu.kanade.tachiyomi.ui.base.controller.FullComposeContentController import eu.kanade.tachiyomi.ui.base.controller.FullComposeContentController
import eu.kanade.tachiyomi.ui.base.controller.NoAppBarElevationController
import eu.kanade.tachiyomi.ui.base.controller.RootController import eu.kanade.tachiyomi.ui.base.controller.RootController
import eu.kanade.tachiyomi.ui.base.controller.TabbedController import eu.kanade.tachiyomi.ui.base.controller.TabbedController
import eu.kanade.tachiyomi.ui.base.controller.pushController import eu.kanade.tachiyomi.ui.base.controller.pushController
@ -639,8 +638,6 @@ class MainActivity : BaseActivity() {
backstackLiftState.remove(it.instanceId) backstackLiftState.remove(it.instanceId)
} }
} }
binding.root.isLiftAppBarOnScroll = internalTo !is NoAppBarElevationController
} }
} }

View file

@ -1,11 +1,9 @@
package eu.kanade.tachiyomi.ui.more package eu.kanade.tachiyomi.ui.more
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import eu.kanade.presentation.more.MoreScreen import eu.kanade.presentation.more.MoreScreen
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.base.controller.ComposeController import eu.kanade.tachiyomi.ui.base.controller.FullComposeController
import eu.kanade.tachiyomi.ui.base.controller.NoAppBarElevationController
import eu.kanade.tachiyomi.ui.base.controller.RootController import eu.kanade.tachiyomi.ui.base.controller.RootController
import eu.kanade.tachiyomi.ui.base.controller.pushController import eu.kanade.tachiyomi.ui.base.controller.pushController
import eu.kanade.tachiyomi.ui.category.CategoryController import eu.kanade.tachiyomi.ui.category.CategoryController
@ -14,18 +12,16 @@ import eu.kanade.tachiyomi.ui.setting.SettingsBackupController
import eu.kanade.tachiyomi.ui.setting.SettingsMainController import eu.kanade.tachiyomi.ui.setting.SettingsMainController
class MoreController : class MoreController :
ComposeController<MorePresenter>(), FullComposeController<MorePresenter>(),
RootController, RootController {
NoAppBarElevationController {
override fun getTitle() = resources?.getString(R.string.label_more) override fun getTitle() = resources?.getString(R.string.label_more)
override fun createPresenter() = MorePresenter() override fun createPresenter() = MorePresenter()
@Composable @Composable
override fun ComposeContent(nestedScrollInterop: NestedScrollConnection) { override fun ComposeContent() {
MoreScreen( MoreScreen(
nestedScrollInterop = nestedScrollInterop,
presenter = presenter, presenter = presenter,
onClickDownloadQueue = { router.pushController(DownloadController()) }, onClickDownloadQueue = { router.pushController(DownloadController()) },
onClickCategories = { router.pushController(CategoryController()) }, onClickCategories = { router.pushController(CategoryController()) },

View file

@ -34,25 +34,9 @@ class TachiyomiCoordinatorLayout @JvmOverloads constructor(
defStyleAttr: Int = R.attr.coordinatorLayoutStyle, defStyleAttr: Int = R.attr.coordinatorLayoutStyle,
) : CoordinatorLayout(context, attrs, defStyleAttr) { ) : CoordinatorLayout(context, attrs, defStyleAttr) {
/**
* Keep lifted state and do nothing on tablet UI
*/
private val isTablet = context.isTablet()
private var appBarLayout: AppBarLayout? = null private var appBarLayout: AppBarLayout? = null
private var tabLayout: TabLayout? = null private var tabLayout: TabLayout? = null
/**
* If true, [AppBarLayout] child will be lifted on nested scroll.
*/
var isLiftAppBarOnScroll = true
/**
* Internal check
*/
private val canLiftAppBarOnScroll
get() = !isTablet && isLiftAppBarOnScroll
override fun onNestedScroll( override fun onNestedScroll(
target: View, target: View,
dxConsumed: Int, dxConsumed: Int,
@ -64,7 +48,7 @@ class TachiyomiCoordinatorLayout @JvmOverloads constructor(
) { ) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type, consumed) super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type, consumed)
// Disable elevation overlay when tabs are visible // Disable elevation overlay when tabs are visible
if (canLiftAppBarOnScroll) { if (context.isTablet().not()) {
if (target is ComposeView) { if (target is ComposeView) {
val scrollCondition = if (type == ViewCompat.TYPE_NON_TOUCH) { val scrollCondition = if (type == ViewCompat.TYPE_NON_TOUCH) {
dyUnconsumed >= 0 dyUnconsumed >= 0