Basic initial port of About screen to Compose

(cherry picked from commit d6c87ec10e7d1bec8c43423c3d7d591ce9fdb798)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
This commit is contained in:
arkon 2022-04-23 12:05:00 -04:00 committed by Jobobby04
parent 2640ae8dd4
commit f537d8396c
10 changed files with 364 additions and 95 deletions

View File

@ -125,6 +125,7 @@ dependencies {
implementation(compose.foundation)
implementation(compose.material3.core)
implementation(compose.material3.adapter)
implementation(compose.material.icons)
implementation(compose.animation)
implementation(compose.ui.tooling)

View File

@ -0,0 +1,39 @@
package eu.kanade.presentation.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.unit.dp
@Composable
fun LinkIcon(
modifier: Modifier = Modifier,
label: String,
painter: Painter,
url: String,
) {
val uriHandler = LocalUriHandler.current
LinkIcon(modifier, label, painter) { uriHandler.openUri(url) }
}
@Composable
fun LinkIcon(
modifier: Modifier = Modifier,
label: String,
painter: Painter,
onClick: () -> Unit,
) {
Icon(
modifier = modifier
.clickable(onClick = onClick)
.padding(16.dp),
painter = painter,
tint = MaterialTheme.colorScheme.primary,
contentDescription = label,
)
}

View File

@ -0,0 +1,89 @@
package eu.kanade.presentation.components
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.util.horizontalPadding
@Composable
fun PreferenceRow(
title: String,
icon: ImageVector? = null,
onClick: () -> Unit = {},
onLongClick: () -> Unit = {},
subtitle: String? = null,
action: @Composable (() -> Unit)? = null,
) {
val height = if (subtitle != null) 72.dp else 56.dp
// TODO: adjust text styles, especially subtitles
val textStyle = MaterialTheme.typography.titleMedium.copy(
color = contentColorFor(MaterialTheme.colorScheme.background),
)
Row(
modifier = Modifier
.fillMaxWidth()
.requiredHeight(height)
.combinedClickable(
onLongClick = onLongClick,
onClick = onClick
),
verticalAlignment = Alignment.CenterVertically
) {
if (icon != null) {
Icon(
imageVector = icon,
modifier = Modifier
.padding(horizontal = horizontalPadding)
.size(24.dp),
tint = MaterialTheme.colorScheme.primary,
contentDescription = null
)
}
Column(
Modifier
.padding(horizontal = horizontalPadding)
.weight(1f)
) {
Text(
text = title,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = textStyle,
)
if (subtitle != null) {
Text(
text = subtitle,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = textStyle.copy(
fontWeight = FontWeight.Normal,
),
)
}
}
if (action != null) {
Box(Modifier.widthIn(min = 56.dp)) {
action()
}
}
}
}

View File

@ -0,0 +1,145 @@
package eu.kanade.presentation.more
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Public
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
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.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import eu.kanade.presentation.components.LinkIcon
import eu.kanade.presentation.components.PreferenceRow
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.CrashLogUtil
import eu.kanade.tachiyomi.util.system.copyToClipboard
import exh.syDebugVersion
@Composable
fun AboutScreen(
nestedScrollInterop: NestedScrollConnection,
checkVersion: () -> Unit,
getFormattedBuildTime: () -> String,
onClickLicenses: () -> Unit,
onClickWhatsNew: () -> Unit,
) {
val context = LocalContext.current
val uriHandler = LocalUriHandler.current
LazyColumn(
modifier = Modifier.nestedScroll(nestedScrollInterop),
) {
item {
LogoHeader()
}
item {
PreferenceRow(
title = stringResource(R.string.version),
subtitle = when {
BuildConfig.DEBUG -> {
"Debug ${BuildConfig.COMMIT_SHA} (${getFormattedBuildTime()})"
}
// SY -->
syDebugVersion != "0" -> {
"Preview r$syDebugVersion (${BuildConfig.COMMIT_SHA}, ${getFormattedBuildTime()})"
}
// SY <--
else -> {
"Stable ${BuildConfig.VERSION_NAME} (${getFormattedBuildTime()})"
}
},
onClick = {
val deviceInfo = CrashLogUtil(context).getDebugInfo()
context.copyToClipboard("Debug information", deviceInfo)
},
)
}
if (BuildConfig.INCLUDE_UPDATER) {
item {
PreferenceRow(
title = stringResource(R.string.check_for_updates),
onClick = {
checkVersion()
},
)
}
}
if (!BuildConfig.DEBUG) {
item {
PreferenceRow(
title = stringResource(R.string.whats_new),
onClick = onClickWhatsNew,
)
}
}
item {
PreferenceRow(
title = stringResource(R.string.help_translate),
onClick = { uriHandler.openUri("https://tachiyomi.org/help/contribution/#translation") },
)
}
item {
PreferenceRow(
title = stringResource(R.string.licenses),
onClick = onClickLicenses,
)
}
item {
PreferenceRow(
title = stringResource(R.string.privacy_policy),
onClick = { uriHandler.openUri("https://tachiyomi.org/privacy") },
)
}
item {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
) {
LinkIcon(
label = stringResource(R.string.website),
painter = rememberVectorPainter(Icons.Outlined.Public),
url = "https://tachiyomi.org",
)
LinkIcon(
label = "Discord",
painter = painterResource(R.drawable.ic_discord_24dp),
url = "https://discord.gg/tachiyomi",
)
LinkIcon(
label = "Twitter",
painter = painterResource(R.drawable.ic_twitter_24dp),
url = "https://twitter.com/tachiyomiorg",
)
LinkIcon(
label = "Facebook",
painter = painterResource(R.drawable.ic_facebook_24dp),
url = "https://facebook.com/tachiyomiorg",
)
LinkIcon(
label = "Reddit",
painter = painterResource(R.drawable.ic_reddit_24dp),
url = "https://www.reddit.com/r/Tachiyomi",
)
LinkIcon(
label = "GitHub",
painter = painterResource(R.drawable.ic_github_24dp),
url = "https://github.com/tachiyomiorg",
)
}
}
}
}

View File

@ -0,0 +1,28 @@
package eu.kanade.presentation.more
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.nestedScroll
import com.mikepenz.aboutlibraries.ui.compose.LibrariesContainer
import com.mikepenz.aboutlibraries.ui.compose.LibraryDefaults
@Composable
fun LicensesScreen(
nestedScrollInterop: NestedScrollConnection,
) {
LibrariesContainer(
modifier = Modifier
.fillMaxSize()
.nestedScroll(nestedScrollInterop),
colors = LibraryDefaults.libraryColors(
backgroundColor = MaterialTheme.colorScheme.background,
contentColor = contentColorFor(MaterialTheme.colorScheme.background),
badgeBackgroundColor = MaterialTheme.colorScheme.primary,
badgeContentColor = contentColorFor(MaterialTheme.colorScheme.primary),
),
)
}

View File

@ -0,0 +1,36 @@
package eu.kanade.presentation.more
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Divider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R
@Composable
fun LogoHeader() {
Column {
Surface(
modifier = Modifier.fillMaxWidth()
) {
Icon(
painter = painterResource(R.drawable.ic_tachi),
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier
.padding(32.dp)
.size(56.dp),
)
}
// TODO: proper color
Divider()
}
}

View File

@ -7,7 +7,6 @@ import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.preference.PreferenceManager
import com.fredporciuncula.flow.preferences.FlowSharedPreferences
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.track.TrackService
@ -22,6 +21,7 @@ import eu.kanade.tachiyomi.ui.reader.setting.ReaderBottomButton
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import eu.kanade.tachiyomi.ui.reader.viewer.pager.PagerConfig
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import java.io.File
import java.text.DateFormat
@ -29,7 +29,6 @@ import java.text.SimpleDateFormat
import java.util.Locale
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values
import eu.kanade.tachiyomi.util.system.isDevFlavor
class PreferencesHelper(val context: Context) {

View File

@ -1,101 +1,48 @@
package eu.kanade.tachiyomi.ui.more
import androidx.preference.PreferenceScreen
import androidx.compose.runtime.Composable
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import eu.kanade.presentation.more.AboutScreen
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.updater.AppUpdateChecker
import eu.kanade.tachiyomi.data.updater.AppUpdateResult
import eu.kanade.tachiyomi.ui.base.controller.BasicComposeController
import eu.kanade.tachiyomi.ui.base.controller.NoAppBarElevationController
import eu.kanade.tachiyomi.ui.base.controller.openInBrowser
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.main.WhatsNewDialogController
import eu.kanade.tachiyomi.ui.setting.SettingsController
import eu.kanade.tachiyomi.util.CrashLogUtil
import eu.kanade.tachiyomi.util.lang.launchNow
import eu.kanade.tachiyomi.util.lang.toDateTimestampString
import eu.kanade.tachiyomi.util.preference.add
import eu.kanade.tachiyomi.util.preference.onClick
import eu.kanade.tachiyomi.util.preference.preference
import eu.kanade.tachiyomi.util.preference.titleRes
import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast
import exh.syDebugVersion
import logcat.LogPriority
import uy.kohesive.injekt.injectLazy
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.TimeZone
class AboutController : SettingsController(), NoAppBarElevationController {
class AboutController : BasicComposeController(), NoAppBarElevationController {
private val preferences: PreferencesHelper by injectLazy()
private val updateChecker by lazy { AppUpdateChecker() }
private val dateFormat: DateFormat = preferences.dateFormat()
override fun getTitle() = resources?.getString(R.string.pref_category_about)
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
titleRes = R.string.pref_category_about
add(MoreHeaderPreference(context))
preference {
key = "pref_about_version"
titleRes = R.string.version
summary = if (BuildConfig.DEBUG /* SY --> */ || syDebugVersion != "0" /* SY --> */) {
"Preview r$syDebugVersion (${BuildConfig.COMMIT_SHA}, ${getFormattedBuildTime()})"
} else {
"Stable ${BuildConfig.VERSION_NAME} (${getFormattedBuildTime()})"
}
onClick {
activity?.let {
val deviceInfo = CrashLogUtil(it).getDebugInfo()
it.copyToClipboard("Debug information", deviceInfo)
}
}
}
if (BuildConfig.INCLUDE_UPDATER) {
preference {
key = "pref_about_check_for_updates"
titleRes = R.string.check_for_updates
onClick { checkVersion() }
}
}
preference {
key = "pref_about_whats_new"
titleRes = R.string.whats_new
onClick {
// SY -->
WhatsNewDialogController().showDialog(router)
// SY <--
}
}
preference {
key = "pref_about_help_translate"
titleRes = R.string.help_translate
onClick {
openInBrowser("https://tachiyomi.org/help/contribution/#translation")
}
}
preference {
key = "pref_about_licenses"
titleRes = R.string.licenses
onClick {
@Composable
override fun ComposeContent(nestedScrollInterop: NestedScrollConnection) {
AboutScreen(
nestedScrollInterop = nestedScrollInterop,
checkVersion = this::checkVersion,
getFormattedBuildTime = this::getFormattedBuildTime,
onClickLicenses = {
router.pushController(LicensesController().withFadeTransaction())
}
}
preference {
key = "pref_about_privacy_policy"
titleRes = R.string.privacy_policy
onClick {
openInBrowser("https://tachiyomi.org/privacy")
}
}
add(AboutLinksPreference(context))
},
onClickWhatsNew = {
WhatsNewDialogController().showDialog(router)
},
)
}
/**
@ -137,7 +84,7 @@ class AboutController : SettingsController(), NoAppBarElevationController {
)
outputDf.timeZone = TimeZone.getDefault()
buildTime!!.toDateTimestampString(dateFormat)
buildTime!!.toDateTimestampString(preferences.dateFormat())
} catch (e: Exception) {
BuildConfig.BUILD_TIME
}

View File

@ -1,14 +1,8 @@
package eu.kanade.tachiyomi.ui.more
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.nestedScroll
import com.mikepenz.aboutlibraries.ui.compose.LibrariesContainer
import com.mikepenz.aboutlibraries.ui.compose.LibraryDefaults.libraryColors
import eu.kanade.presentation.more.LicensesScreen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.base.controller.BasicComposeController
@ -18,16 +12,6 @@ class LicensesController : BasicComposeController() {
@Composable
override fun ComposeContent(nestedScrollInterop: NestedScrollConnection) {
LibrariesContainer(
modifier = Modifier
.fillMaxSize()
.nestedScroll(nestedScrollInterop),
colors = libraryColors(
backgroundColor = MaterialTheme.colorScheme.background,
contentColor = contentColorFor(MaterialTheme.colorScheme.background),
badgeBackgroundColor = MaterialTheme.colorScheme.primary,
badgeContentColor = contentColorFor(MaterialTheme.colorScheme.primary),
),
)
LicensesScreen(nestedScrollInterop = nestedScrollInterop)
}
}

View File

@ -5,5 +5,6 @@ compose = "1.2.0-alpha07"
foundation = { module = "androidx.compose.foundation:foundation", version.ref="compose" }
material3-core = "androidx.compose.material3:material3:1.0.0-alpha09"
material3-adapter = "com.google.android.material:compose-theme-adapter-3:1.0.6"
material-icons = { module = "androidx.compose.material:material-icons-extended", version.ref="compose" }
animation = { module = "androidx.compose.animation:animation", version.ref="compose" }
ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref="compose" }