Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding logs to Automotive #1277

Merged
merged 2 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
7.46
-----

* New Feature:
* Added a support section to the Automotive app
([#1277](https://github.com/Automattic/pocket-casts-android/pull/1277))

7.45
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ import au.com.shiftyjelly.pocketcasts.compose.components.HorizontalDivider
import au.com.shiftyjelly.pocketcasts.compose.theme
import au.com.shiftyjelly.pocketcasts.extensions.openUrl
import au.com.shiftyjelly.pocketcasts.localization.BuildConfig
import au.com.shiftyjelly.pocketcasts.localization.R
import au.com.shiftyjelly.pocketcasts.preferences.Settings
import au.com.shiftyjelly.pocketcasts.settings.LogsFragment
import au.com.shiftyjelly.pocketcasts.ui.extensions.getThemeDrawable
import au.com.shiftyjelly.pocketcasts.ui.helper.FragmentHostListener
import dagger.hilt.android.AndroidEntryPoint
import au.com.shiftyjelly.pocketcasts.localization.R as LR
import au.com.shiftyjelly.pocketcasts.ui.R as UR

@AndroidEntryPoint
Expand All @@ -51,6 +52,7 @@ class AutomotiveAboutFragment : Fragment() {
AutomotiveTheme {
AboutPage(
onOpenLicenses = { openLicenses() },
onOpenLogs = { onOpenLogs() },
onOpenUrl = { openUrl(it) }
)
}
Expand All @@ -61,10 +63,18 @@ class AutomotiveAboutFragment : Fragment() {
private fun openLicenses() {
(activity as? FragmentHostListener)?.addFragment(AutomotiveLicensesFragment())
}

private fun onOpenLogs() {
(activity as? FragmentHostListener)?.addFragment(LogsFragment())
}
}

@Composable
private fun AboutPage(onOpenLicenses: () -> Unit, onOpenUrl: (String) -> Unit) {
private fun AboutPage(
onOpenLicenses: () -> Unit,
onOpenLogs: () -> Unit,
onOpenUrl: (String) -> Unit
) {
val context = LocalContext.current
val scrollState = rememberScrollState()
Column(
Expand All @@ -73,44 +83,60 @@ private fun AboutPage(onOpenLicenses: () -> Unit, onOpenUrl: (String) -> Unit) {
) {
Image(
painter = painterResource(context.getThemeDrawable(UR.attr.logo_title_vertical)),
contentDescription = stringResource(R.string.settings_app_icon),
contentDescription = stringResource(LR.string.settings_app_icon),
modifier = Modifier
.padding(top = 56.dp)
.size(width = 220.dp, height = 132.dp)
)
Text(
text = stringResource(R.string.settings_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE.toString()),
text = stringResource(LR.string.settings_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE.toString()),
fontSize = 24.sp,
modifier = Modifier.padding(top = 16.dp),
color = MaterialTheme.theme.colors.primaryText02
)
HorizontalDivider(
modifier = Modifier.padding(top = 56.dp, bottom = 16.dp)
)
Text(
text = stringResource(R.string.settings_about_legal),
fontSize = 24.sp,
fontWeight = FontWeight(500),
letterSpacing = 0.25.sp,
color = MaterialTheme.theme.colors.primaryInteractive01,
modifier = Modifier.align(Alignment.Start).padding(horizontal = 48.dp, vertical = 16.dp)
)
SubTitle(stringResource(LR.string.settings_about_legal))
TextLinkButton(
text = stringResource(R.string.settings_about_terms_of_serivce),
text = stringResource(LR.string.settings_about_terms_of_serivce),
onClick = { onOpenUrl(Settings.INFO_TOS_URL) }
)
TextLinkButton(
text = stringResource(R.string.settings_about_privacy_policy),
text = stringResource(LR.string.settings_about_privacy_policy),
onClick = { onOpenUrl(Settings.INFO_PRIVACY_URL) }
)
TextLinkButton(
text = stringResource(R.string.settings_about_acknowledgements),
text = stringResource(LR.string.settings_about_acknowledgements),
onClick = { onOpenLicenses() }
)
SubTitle(stringResource(LR.string.support))
TextLinkButton(
text = stringResource(LR.string.settings_title_help),
onClick = { onOpenUrl(Settings.INFO_FAQ_URL) }
)
TextLinkButton(
text = stringResource(LR.string.settings_logs),
onClick = { onOpenLogs() }
)
Spacer(Modifier.height(15.dp))
}
}

@Composable
private fun SubTitle(title: String, modifier: Modifier = Modifier) {
Text(
text = title,
fontSize = 24.sp,
fontWeight = FontWeight(500),
letterSpacing = 0.25.sp,
color = MaterialTheme.theme.colors.primaryInteractive01,
modifier = modifier
.padding(horizontal = 48.dp, vertical = 16.dp)
.fillMaxWidth()
)
}

@Composable
private fun TextLinkButton(text: String, onClick: () -> Unit, modifier: Modifier = Modifier) {
Row(
Expand All @@ -131,5 +157,5 @@ private fun TextLinkButton(text: String, onClick: () -> Unit, modifier: Modifier
@Composable
@Preview
private fun AboutPageRow() {
AboutPage(onOpenLicenses = {}, onOpenUrl = {})
AboutPage(onOpenLicenses = {}, onOpenLogs = {}, onOpenUrl = {})
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import au.com.shiftyjelly.pocketcasts.repositories.user.UserManager
import au.com.shiftyjelly.pocketcasts.utils.SentryHelper
import au.com.shiftyjelly.pocketcasts.utils.SentryHelper.AppPlatform
import au.com.shiftyjelly.pocketcasts.utils.TimberDebugTree
import au.com.shiftyjelly.pocketcasts.utils.log.LogBuffer
import au.com.shiftyjelly.pocketcasts.utils.log.RxJavaUncaughtExceptionHandling
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
Expand All @@ -31,6 +32,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.File
import java.util.concurrent.Executors
import javax.inject.Inject

Expand Down Expand Up @@ -112,10 +114,10 @@ class AutomotiveApplication : Application(), Configuration.Provider {
}

private fun setupLogging() {
// TODO uncomment this after we have playback issues resolved
// if (BuildConfig.DEBUG) {
Timber.plant(TimberDebugTree())
// }
LogBuffer.setup(File(filesDir, "logs").absolutePath)
if (BuildConfig.DEBUG) {
Timber.plant(TimberDebugTree())
}
}

private fun setupAnalytics() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class HelpFragment : Fragment(), HasBackstack, Toolbar.OnMenuItemClickListener {

webView = (view.findViewById<View>(VR.id.webview) as WebView).apply {
webViewClient = SupportWebViewClient()
loadUrl(loadedUrl ?: "https://support.pocketcasts.com/android/?device=android")
loadUrl(loadedUrl ?: Settings.INFO_FAQ_URL)
settings.javaScriptEnabled = true
settings.textZoom = 100
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CopyAll
import androidx.compose.material.icons.filled.Share
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
Expand All @@ -23,14 +24,19 @@ import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import au.com.shiftyjelly.pocketcasts.compose.AppThemeWithBackground
import au.com.shiftyjelly.pocketcasts.compose.bars.ThemedTopAppBar
import au.com.shiftyjelly.pocketcasts.compose.components.TextH30
import au.com.shiftyjelly.pocketcasts.compose.components.TextP60
import au.com.shiftyjelly.pocketcasts.compose.loading.LoadingView
import au.com.shiftyjelly.pocketcasts.compose.preview.ThemePreviewParameterProvider
import au.com.shiftyjelly.pocketcasts.settings.viewmodel.LogsViewModel
import au.com.shiftyjelly.pocketcasts.ui.helper.FragmentHostListener
import au.com.shiftyjelly.pocketcasts.ui.theme.Theme
import au.com.shiftyjelly.pocketcasts.utils.Util
import au.com.shiftyjelly.pocketcasts.views.fragments.BaseFragment
import dagger.hilt.android.AndroidEntryPoint
import au.com.shiftyjelly.pocketcasts.localization.R as LR
Expand Down Expand Up @@ -64,53 +70,110 @@ private fun LogsPage(
val clipboardManager = LocalClipboardManager.current
val context = LocalContext.current

Column {

ThemedTopAppBar(
title = stringResource(LR.string.settings_logs),
onNavigationClick = onBackPressed,
actions = {
IconButton(
onClick = {
logs?.let {
clipboardManager.setText(AnnotatedString(it))
}
},
enabled = logs != null
) {
Icon(
imageVector = Icons.Default.CopyAll,
contentDescription = stringResource(LR.string.share)
)
}

IconButton(
onClick = { viewModel.shareLogs(context) },
enabled = logs != null
) {
Icon(
imageVector = Icons.Default.Share,
contentDescription = stringResource(LR.string.share)
)
}
}
)
LogsContent(
onBackPressed = onBackPressed,
onCopyToClipboard = { logs?.let { clipboardManager.setText(AnnotatedString(it)) } },
onShareLogs = { viewModel.shareLogs(context) },
includeAppBar = !Util.isAutomotive(context),
logs = logs
)
}

@Composable
private fun LogsContent(
onBackPressed: () -> Unit,
onCopyToClipboard: () -> Unit,
onShareLogs: () -> Unit,
logs: String?,
includeAppBar: Boolean
) {
val logScrollState = rememberScrollState(0)
Column {
if (includeAppBar) {
AppBarWithShare(
onBackPressed = onBackPressed,
onCopyToClipboard = onCopyToClipboard,
onShareLogs = onShareLogs,
logsAvailable = logs != null
)
}
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
.verticalScroll(logScrollState)
.padding(16.dp)
.fillMaxWidth()
) {

if (logs == null) {
TextH30(
text = stringResource(LR.string.loading),
modifier = Modifier.padding(vertical = 24.dp)
)
LoadingView()
} else {
TextP60(logs)
}
}
}
// scroll to the end to show the latest logs
LaunchedEffect(logs) {
logScrollState.scrollTo(logScrollState.maxValue)
}
}

@Composable
private fun AppBarWithShare(
onBackPressed: () -> Unit,
onCopyToClipboard: () -> Unit,
onShareLogs: () -> Unit,
logsAvailable: Boolean,
modifier: Modifier = Modifier
) {
ThemedTopAppBar(
title = stringResource(LR.string.settings_logs),
onNavigationClick = onBackPressed,
actions = {
IconButton(
onClick = onCopyToClipboard,
enabled = logsAvailable
) {
Icon(
imageVector = Icons.Default.CopyAll,
contentDescription = stringResource(LR.string.share)
)
}
IconButton(
onClick = onShareLogs,
enabled = logsAvailable
) {
Icon(
imageVector = Icons.Default.Share,
contentDescription = stringResource(LR.string.share)
)
}
},
modifier = modifier
)
}

@Composable
@Preview
private fun LogsContentPreview(@PreviewParameter(ThemePreviewParameterProvider::class) themeType: Theme.ThemeType) {
AppThemeWithBackground(themeType) {
LogsContent(
onBackPressed = {},
onCopyToClipboard = {},
onShareLogs = {},
logs = "This is a preview",
includeAppBar = true
)
}
}
@Composable
@Preview
private fun LogsContentLoadingPreview(@PreviewParameter(ThemePreviewParameterProvider::class) themeType: Theme.ThemeType) {
AppThemeWithBackground(themeType) {
LogsContent(
onBackPressed = {},
onCopyToClipboard = {},
onShareLogs = {},
logs = null,
includeAppBar = true
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
<string name="please_try_again">Please try again</string>
<string name="next">Next</string>
<string name="select_podcasts">Select podcasts</string>
<string name="support">Support</string>

<string name="multiselect_actions_shown">Shortcut in toolbar</string>
<string name="multiselect_actions_hidden">In overflow</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ interface Settings {
const val INFO_TOS_URL = "https://support.pocketcasts.com/article/terms-of-use-overview/"
const val INFO_PRIVACY_URL = "https://support.pocketcasts.com/article/privacy-policy/"
const val INFO_CANCEL_URL = "https://support.pocketcasts.com/article/subscription-info/"
const val INFO_FAQ_URL = "https://support.pocketcasts.com/android/?device=android"

const val USER_AGENT_POCKETCASTS_SERVER = "Pocket Casts/Android/" + BuildConfig.VERSION_NAME

Expand Down
Loading