From 9716fb56fffd817386b294c6b6e48bc49cf71f2f Mon Sep 17 00:00:00 2001 From: Uwe Trottmann Date: Fri, 12 Jan 2024 11:37:02 +0100 Subject: [PATCH] Compose: use composable to build AboutActivity UI. --- .../seriesguide/preferences/AboutActivity.kt | 190 ++++++++++++++++-- .../preferences/AboutPreferencesFragment.kt | 75 ------- app/src/main/res/layout/activity_about.xml | 19 -- 3 files changed, 172 insertions(+), 112 deletions(-) delete mode 100644 app/src/main/java/com/battlelancer/seriesguide/preferences/AboutPreferencesFragment.kt delete mode 100644 app/src/main/res/layout/activity_about.xml diff --git a/app/src/main/java/com/battlelancer/seriesguide/preferences/AboutActivity.kt b/app/src/main/java/com/battlelancer/seriesguide/preferences/AboutActivity.kt index 8cdf604b81..d51585078e 100644 --- a/app/src/main/java/com/battlelancer/seriesguide/preferences/AboutActivity.kt +++ b/app/src/main/java/com/battlelancer/seriesguide/preferences/AboutActivity.kt @@ -1,38 +1,192 @@ -// Copyright 2023 Uwe Trottmann // SPDX-License-Identifier: Apache-2.0 +// Copyright 2021-2023 Uwe Trottmann package com.battlelancer.seriesguide.preferences import android.os.Bundle -import android.view.MenuItem +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.annotation.StringRes +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material3.FilledTonalButton +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Devices +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import com.battlelancer.seriesguide.R -import com.battlelancer.seriesguide.ui.BaseThemeActivity -import com.battlelancer.seriesguide.util.ThemeUtils +import com.battlelancer.seriesguide.ui.theme.SeriesGuideTheme +import com.battlelancer.seriesguide.util.PackageTools +import com.battlelancer.seriesguide.util.WebTools /** - * Just hosts a [AboutPreferencesFragment]. + * Displays details about the app version, links to credits and terms. */ -class AboutActivity : BaseThemeActivity() { +class AboutActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_about) - ThemeUtils.configureForEdgeToEdge(findViewById(R.id.rootLayoutAbout)) - setupActionBar() + + // FIXME How to do this? +// ThemeUtils.configureForEdgeToEdge(findViewById(R.id.rootLayoutAbout)) + + setContent { + SeriesGuideTheme { + About( + versionString = PackageTools.getVersionString(this), + onBackPressed = { onBackPressedDispatcher.onBackPressed() }, + onOpenWebsite = { viewUrl(R.string.url_website) }, + onOpenPrivacyPolicy = { viewUrl(R.string.url_privacy) }, + onOpenCredits = { viewUrl(R.string.url_credits) }, + onOpenTmdbTerms = { viewUrl(R.string.url_terms_tmdb) }, + onOpenTmdbApiTerms = { viewUrl(R.string.url_terms_tmdb_api) }, + onOpenTraktTerms = { viewUrl(R.string.url_terms_trakt) } + ) + } + } } - override fun setupActionBar() { - super.setupActionBar() - supportActionBar?.setDisplayHomeAsUpEnabled(true) + private val defaultSpacerSize = 16.dp + + @Composable + fun SgTopAppBar( + titleStringRes: Int, + onBackPressed: () -> Unit + ) { + TopAppBar( + title = { + Text( + text = stringResource(id = titleStringRes), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + }, + navigationIcon = { + IconButton(onClick = onBackPressed) { + Icon( + imageVector = Icons.Filled.ArrowBack, + contentDescription = stringResource(id = R.string.navigate_back) + ) + } + } + ) } - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - android.R.id.home -> { - onBackPressedDispatcher.onBackPressed() - true + @Composable + fun About( + versionString: String, + onBackPressed: () -> Unit, + onOpenWebsite: () -> Unit, + onOpenPrivacyPolicy: () -> Unit, + onOpenCredits: () -> Unit, + onOpenTmdbTerms: () -> Unit, + onOpenTmdbApiTerms: () -> Unit, + onOpenTraktTerms: () -> Unit + ) { + Scaffold( + topBar = { + SgTopAppBar(R.string.prefs_category_about, onBackPressed) + } + ) { scaffoldPadding -> + BoxWithConstraints( + modifier = Modifier + .padding(scaffoldPadding) + .fillMaxWidth() + ) { + val scrollAndPadding = Modifier + .verticalScroll(rememberScrollState()) + .padding(defaultSpacerSize) + Column( + // if 600 dp or wider center align + modifier = if (maxWidth < 600.dp) { + scrollAndPadding + } else { + scrollAndPadding + .width(600.dp) + .align(Alignment.Center) + } + ) { + Text( + text = stringResource(id = R.string.app_name), + style = MaterialTheme.typography.headlineLarge + ) + Text( + text = versionString, + style = MaterialTheme.typography.bodyLarge + ) + FilledTonalButton(onClick = onOpenWebsite) { + Text(text = stringResource(id = R.string.website)) + } + FilledTonalButton(onClick = onOpenPrivacyPolicy) { + Text(text = stringResource(id = R.string.privacy_policy)) + } + Text( + text = stringResource(id = R.string.about_open_source), + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier.padding(top = 16.dp) + ) + FilledTonalButton(onClick = onOpenCredits) { + Text(text = stringResource(id = R.string.licences_and_credits)) + } + Text( + text = stringResource(id = R.string.licence_themoviedb), + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier.padding(top = 16.dp) + ) + FilledTonalButton(onClick = onOpenTmdbTerms) { + Text(text = stringResource(id = R.string.tmdb_terms)) + } + FilledTonalButton(onClick = onOpenTmdbApiTerms) { + Text(text = stringResource(id = R.string.tmdb_api_terms)) + } + Text( + text = stringResource(id = R.string.licence_trakt), + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier.padding(top = 16.dp) + ) + FilledTonalButton(onClick = onOpenTraktTerms) { + Text(text = stringResource(id = R.string.trakt_terms)) + } + } } - else -> super.onOptionsItemSelected(item) } } + @Preview() + @Preview(device = Devices.PIXEL_C) + @Composable + fun AboutPreview() { + About( + "v42 (Database v42)", + {}, + {}, + {}, + {}, + {}, + {}, + {} + ) + } + + private fun viewUrl(@StringRes urlResId: Int) { + WebTools.openInApp(this, getString(urlResId)) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/battlelancer/seriesguide/preferences/AboutPreferencesFragment.kt b/app/src/main/java/com/battlelancer/seriesguide/preferences/AboutPreferencesFragment.kt deleted file mode 100644 index 59f4100540..0000000000 --- a/app/src/main/java/com/battlelancer/seriesguide/preferences/AboutPreferencesFragment.kt +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2023 Uwe Trottmann -// SPDX-License-Identifier: Apache-2.0 - -package com.battlelancer.seriesguide.preferences - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.annotation.IdRes -import androidx.annotation.StringRes -import androidx.fragment.app.Fragment -import com.battlelancer.seriesguide.R -import com.battlelancer.seriesguide.databinding.FragmentAboutBinding -import com.battlelancer.seriesguide.util.PackageTools -import com.battlelancer.seriesguide.util.ThemeUtils -import com.battlelancer.seriesguide.util.WebTools - -/** - * Displays information about the app, the developer and licence information about content and - * libraries. - */ -class AboutPreferencesFragment : Fragment() { - - private var binding: FragmentAboutBinding? = null - private val urlButtonClickListener = View.OnClickListener { onWebsiteButtonClick(it.id) } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - return FragmentAboutBinding.inflate(inflater, container, false).also { - binding = it - }.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - binding!!.apply { - ThemeUtils.applyBottomPaddingForNavigationBar(scrollViewAbout) - - // display version number and database version - textViewAboutVersion.text = PackageTools.getVersionString(requireContext()) - - buttonAboutWebsite.setOnClickListener(urlButtonClickListener) - buttonAboutPrivacy.setOnClickListener(urlButtonClickListener) - buttonAboutTmdbTerms.setOnClickListener(urlButtonClickListener) - buttonAboutTmdbApiTerms.setOnClickListener(urlButtonClickListener) - buttonAboutTraktTerms.setOnClickListener(urlButtonClickListener) - buttonAboutCredits.setOnClickListener(urlButtonClickListener) - } - } - - override fun onDestroyView() { - super.onDestroyView() - binding = null - } - - private fun onWebsiteButtonClick(@IdRes viewId: Int) { - when (viewId) { - R.id.buttonAboutWebsite -> viewUrl(R.string.url_website) - R.id.buttonAboutPrivacy -> viewUrl(R.string.url_privacy) - R.id.buttonAboutTmdbTerms -> viewUrl(R.string.url_terms_tmdb) - R.id.buttonAboutTmdbApiTerms -> viewUrl(R.string.url_terms_tmdb_api) - R.id.buttonAboutTraktTerms -> viewUrl(R.string.url_terms_trakt) - R.id.buttonAboutCredits -> viewUrl(R.string.url_credits) - } - } - - private fun viewUrl(@StringRes urlResId: Int) { - WebTools.openInApp(requireContext(), getString(urlResId)) - } -} diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml deleted file mode 100644 index d556861fca..0000000000 --- a/app/src/main/res/layout/activity_about.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - \ No newline at end of file