From 67385b65be30faa3fe46d19a8dd4582fff0a0758 Mon Sep 17 00:00:00 2001 From: Kshitij Chauhan Date: Sat, 20 Nov 2021 11:28:06 +0530 Subject: [PATCH 1/9] feat: Switch to versions catalog and AGP 7 --- build.gradle | 4 ++-- gradle/libs.versions.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 613bb94..269831a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,9 @@ buildscript { ext.buildConfig = [ "applicationId": "com.haroldadmin.crashyapp", - "compileSdk" : 29, + "compileSdk" : 31, "minSdk" : 21, - "targetSdk" : 29, + "targetSdk" : 31, "versionCode" : 1, "versionName" : "0.0.1" ] diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2a3d007..c0818f1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] -kotlin = "1.5.20" -agp = "4.2.0" +kotlin = "1.6.0" +agp = "7.0.3" ktlint = "10.1.0" appCompat = "1.3.0" coreTest = "2.0.0" From dcfbec2d638bb5e79435fc80ad39a90ee558ff02 Mon Sep 17 00:00:00 2001 From: Kshitij Chauhan Date: Sat, 27 Nov 2021 15:18:05 +0530 Subject: [PATCH 2/9] feat: Refactor library module to use jetpack compose --- .idea/compiler.xml | 2 +- .idea/inspectionProfiles/Project_Default.xml | 23 ++ .idea/misc.xml | 13 +- app/src/main/AndroidManifest.xml | 4 +- gradle/libs.versions.toml | 11 +- what-the-stack/build.gradle | 11 + .../whatthestack/ExceptionProcessor.kt | 2 +- .../whatthestack/WhatTheStackActivity.kt | 109 ++------- .../whatthestack/WhatTheStackConnection.kt | 2 +- .../ui/components/IconOutlinedButton.kt | 38 +++ .../ui/components/OverlineLabel.kt | 20 ++ .../ui/components/ScrollableText.kt | 27 +++ .../whatthestack/ui/pages/ExceptionPage.kt | 228 ++++++++++++++++++ .../whatthestack/ui/preview/SampleData.kt | 32 +++ .../ui/theme/WhatTheStackTheme.kt | 38 +++ .../res/layout/activity_what_the_stack.xml | 183 -------------- .../src/main/res/values/strings.xml | 13 +- 17 files changed, 472 insertions(+), 284 deletions(-) create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/IconOutlinedButton.kt create mode 100644 what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/OverlineLabel.kt create mode 100644 what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/ScrollableText.kt create mode 100644 what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/pages/ExceptionPage.kt create mode 100644 what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/preview/SampleData.kt create mode 100644 what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/theme/WhatTheStackTheme.kt delete mode 100644 what-the-stack/src/main/res/layout/activity_what_the_stack.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 61a9130..fb7f4a8 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..875a112 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,23 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 7bb9736..09c0d79 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,18 @@ + + + - + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6840f78..d2e0d1f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,7 +9,9 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> - + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c0818f1..1242fee 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -kotlin = "1.6.0" +kotlin = "1.5.31" agp = "7.0.3" ktlint = "10.1.0" appCompat = "1.3.0" @@ -17,9 +17,18 @@ espressoCore = "3.2.0" mockk = "1.9.3" robolectric = "4.3.1" startup = "1.0.0" +composeActivity = "1.3.1" +composeMaterial = "1.0.5" +composeTooling = "1.0.5" +accompanist = "0.21.3-beta" [libraries] +composeActivity = { module = "androidx.activity:activity-compose", version.ref = "composeActivity" } +composeMaterial = { module = "androidx.compose.material:material", version.ref = "composeMaterial" } +composeTooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "composeTooling" } +accompanistSysUi = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" } +accompanistInsets = { module = "com.google.accompanist:accompanist-insets", version.ref = "accompanist" } agp = { module = "com.android.tools.build:gradle", version.ref = "agp" } kotlinGradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } ktlintGradlePlugin = { module = "org.jlleitschuh.gradle:ktlint-gradle", version.ref = "ktlint" } diff --git a/what-the-stack/build.gradle b/what-the-stack/build.gradle index 564ebb8..c6d3657 100644 --- a/what-the-stack/build.gradle +++ b/what-the-stack/build.gradle @@ -37,6 +37,11 @@ android { buildFeatures { viewBinding true + compose true + } + + composeOptions { + kotlinCompilerExtensionVersion "1.0.5" } } @@ -52,6 +57,12 @@ dependencies { implementation libs.startup implementation libs.insetter + implementation libs.composeActivity + implementation libs.composeMaterial + implementation libs.composeTooling + implementation libs.accompanistSysUi + implementation libs.accompanistInsets + testImplementation libs.junit testImplementation libs.mockk diff --git a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ExceptionProcessor.kt b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ExceptionProcessor.kt index d02d8bb..2d564a5 100644 --- a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ExceptionProcessor.kt +++ b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ExceptionProcessor.kt @@ -1,7 +1,7 @@ package com.haroldadmin.whatthestack import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize /** * Represents the data of the exception to be displayed to the user. diff --git a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/WhatTheStackActivity.kt b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/WhatTheStackActivity.kt index 54c46c6..108afee 100644 --- a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/WhatTheStackActivity.kt +++ b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/WhatTheStackActivity.kt @@ -1,18 +1,14 @@ package com.haroldadmin.whatthestack -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context -import android.content.Intent -import android.net.Uri import android.os.Bundle -import android.text.method.ScrollingMovementMethod +import androidx.activity.compose.setContent import androidx.appcompat.app.AppCompatActivity import androidx.core.view.WindowCompat -import com.google.android.material.snackbar.Snackbar -import com.haroldadmin.whatthestack.databinding.ActivityWhatTheStackBinding -import dev.chrisbanes.insetter.Insetter -import dev.chrisbanes.insetter.windowInsetTypesOf +import com.google.accompanist.insets.ProvideWindowInsets +import com.google.accompanist.systemuicontroller.rememberSystemUiController +import com.haroldadmin.whatthestack.ui.pages.ExceptionPage +import com.haroldadmin.whatthestack.ui.theme.SystemBarsColor +import com.haroldadmin.whatthestack.ui.theme.WhatTheStackTheme /** * An Activity which displays various pieces of information regarding the exception which @@ -20,90 +16,27 @@ import dev.chrisbanes.insetter.windowInsetTypesOf */ class WhatTheStackActivity : AppCompatActivity() { - private lateinit var binding: ActivityWhatTheStackBinding - - private val clipboardManager: ClipboardManager by lazy { - getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = ActivityWhatTheStackBinding.inflate(layoutInflater) - setContentView(binding.root) - WindowCompat.setDecorFitsSystemWindows(window, false) - Insetter.builder() - .padding(windowInsetTypesOf(statusBars = true, navigationBars = true)) - .applyToView(binding.root) - - val type = intent.getStringExtra(KEY_EXCEPTION_TYPE) - val cause = intent.getStringExtra(KEY_EXCEPTION_CAUSE) - val message = intent.getStringExtra(KEY_EXCEPTION_MESSAGE) - val stackTrace = intent.getStringExtra(KEY_EXCEPTION_STACKTRACE) - - binding.stacktrace.apply { - text = stackTrace - setHorizontallyScrolling(true) - movementMethod = ScrollingMovementMethod() - } - - binding.exceptionName.apply { - text = getString(R.string.exception_name, type) - } - - binding.exceptionCause.apply { - text = getString(R.string.exception_cause, cause) - } - - binding.exceptionMessage.apply { - text = getString(R.string.exception_message, message) - } - - binding.copyStacktrace.apply { - setOnClickListener { - val clipping = ClipData.newPlainText("stacktrace", stackTrace) - clipboardManager.setPrimaryClip(clipping) - snackbar { R.string.copied_message } - } - } - - binding.shareStacktrace.apply { - setOnClickListener { - val sendIntent: Intent = Intent().apply { - this.action = Intent.ACTION_SEND - this.putExtra(Intent.EXTRA_TEXT, stackTrace) - this.type = "text/plain" + val type = intent.getStringExtra(KEY_EXCEPTION_TYPE) ?: "" + val message = intent.getStringExtra(KEY_EXCEPTION_MESSAGE) ?: "" + val stackTrace = intent.getStringExtra(KEY_EXCEPTION_STACKTRACE) ?: "" + + setContent { + val sysUiController = rememberSystemUiController() + sysUiController.setSystemBarsColor(SystemBarsColor) + + WhatTheStackTheme { + ProvideWindowInsets { + ExceptionPage( + type = type, + message = message, + stackTrace = stackTrace + ) } - - val shareIntent = Intent.createChooser(sendIntent, null) - startActivity(shareIntent) - } - } - - binding.launchApplication.apply { - setOnClickListener { - context.packageManager.getLaunchIntentForPackage(applicationContext.packageName) - ?.let { - it.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK - startActivity(it) - } } } - - binding.searchStackoverflow.apply { - setOnClickListener { - val searchQuery = "$cause: $message" - val searchIntent: Intent = Intent().apply { - this.action = Intent.ACTION_VIEW - this.data = Uri.parse(generateStackoverflowSearchUrl(searchQuery)) - } - startActivity(searchIntent) - } - } - } - - private inline fun snackbar(messageProvider: () -> Int) { - Snackbar.make(binding.nestedScrollRoot, messageProvider(), Snackbar.LENGTH_SHORT).show() } } diff --git a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/WhatTheStackConnection.kt b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/WhatTheStackConnection.kt index 16df4d5..3e1f45b 100644 --- a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/WhatTheStackConnection.kt +++ b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/WhatTheStackConnection.kt @@ -5,7 +5,7 @@ import android.content.ServiceConnection import android.os.IBinder internal class WhatTheStackConnection( - private val onDisconnected: () -> Unit = { Unit }, + private val onDisconnected: () -> Unit = { }, private val onConnected: (IBinder) -> Unit ) : ServiceConnection { diff --git a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/IconOutlinedButton.kt b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/IconOutlinedButton.kt new file mode 100644 index 0000000..6778d02 --- /dev/null +++ b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/IconOutlinedButton.kt @@ -0,0 +1,38 @@ +package com.haroldadmin.whatthestack.ui.components + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign + +@Composable +internal fun OutlinedIconButton( + text: String, + @DrawableRes iconId: Int, + onClick: () -> Unit, + contentDescription: String, + modifier: Modifier = Modifier, +) { + OutlinedButton( + onClick = onClick, + modifier = modifier.fillMaxWidth(), + colors = ButtonDefaults.outlinedButtonColors( + backgroundColor = MaterialTheme.colors.background, + contentColor = MaterialTheme.colors.onBackground, + disabledContentColor = MaterialTheme.colors.onBackground.copy(alpha = 0.5f) + ), + ) { + Icon( + painter = painterResource(id = iconId), + contentDescription = contentDescription + ) + Text( + text = text, + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center, + ) + } +} \ No newline at end of file diff --git a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/OverlineLabel.kt b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/OverlineLabel.kt new file mode 100644 index 0000000..2742be5 --- /dev/null +++ b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/OverlineLabel.kt @@ -0,0 +1,20 @@ +package com.haroldadmin.whatthestack.ui.components + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +/** + * A text label with the "overline" typography style + */ +@Composable +internal fun OverlineLabel(label: String, modifier: Modifier = Modifier) { + Text( + text = label, + style = MaterialTheme.typography.overline, + color = if (isSystemInDarkTheme()) MaterialTheme.colors.primary else MaterialTheme.colors.primaryVariant, + modifier = modifier + ) +} \ No newline at end of file diff --git a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/ScrollableText.kt b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/ScrollableText.kt new file mode 100644 index 0000000..d506aaf --- /dev/null +++ b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/components/ScrollableText.kt @@ -0,0 +1,27 @@ +package com.haroldadmin.whatthestack.ui.components + +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.rememberScrollState +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily + +@Composable +internal fun ScrollableText( + text: String, + style: TextStyle, + fontFamily: FontFamily, + modifier: Modifier = Modifier, + color: Color = Color.Unspecified, +) { + Text( + text = text, + style = style, + fontFamily = fontFamily, + color = color, + modifier = modifier.horizontalScroll(rememberScrollState()) + ) +} \ No newline at end of file diff --git a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/pages/ExceptionPage.kt b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/pages/ExceptionPage.kt new file mode 100644 index 0000000..71c310c --- /dev/null +++ b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/pages/ExceptionPage.kt @@ -0,0 +1,228 @@ +package com.haroldadmin.whatthestack.ui.pages + +import android.content.Intent +import android.content.res.Configuration.UI_MODE_NIGHT_YES +import android.net.Uri +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.selection.SelectionContainer +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +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.text.font.FontFamily +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.google.accompanist.insets.navigationBarsHeight +import com.google.accompanist.insets.statusBarsHeight +import com.haroldadmin.whatthestack.R +import com.haroldadmin.whatthestack.generateStackoverflowSearchUrl +import com.haroldadmin.whatthestack.ui.components.OutlinedIconButton +import com.haroldadmin.whatthestack.ui.components.OverlineLabel +import com.haroldadmin.whatthestack.ui.components.ScrollableText +import com.haroldadmin.whatthestack.ui.preview.SampleData +import com.haroldadmin.whatthestack.ui.theme.WhatTheStackTheme +import kotlinx.coroutines.launch + +@Composable +fun ExceptionPage( + type: String, + message: String, + stackTrace: String +) { + val clipboard = LocalClipboardManager.current + val context = LocalContext.current + val scaffoldState = rememberScaffoldState() + val coroutineScope = rememberCoroutineScope() + + val snackbarMessage = stringResource(id = R.string.copied_message) + + Scaffold(scaffoldState = scaffoldState) { + Column( + modifier = Modifier + .padding(horizontal = 8.dp) + .verticalScroll(rememberScrollState()) + ) { + Spacer(modifier = Modifier.statusBarsHeight(additional = 8.dp)) + PageHeader() + ExceptionDetails( + type = type, + message = message, + modifier = Modifier.padding(vertical = 8.dp) + ) + ExceptionOptions( + onCopy = { + coroutineScope.launch { + clipboard.setText(AnnotatedString(stackTrace)) + scaffoldState.snackbarHostState.showSnackbar(snackbarMessage) + } + }, + onShare = { + val sendIntent: Intent = Intent().apply { + this.action = Intent.ACTION_SEND + this.putExtra(Intent.EXTRA_TEXT, stackTrace) + this.type = "text/plain" + } + + val shareIntent = Intent.createChooser(sendIntent, "Stacktrace") + context.startActivity(shareIntent) + }, + onSearch = { + val searchQuery = "$type: $message" + val url = generateStackoverflowSearchUrl(searchQuery) + val searchIntent = Intent().apply { + action = Intent.ACTION_VIEW + data = Uri.parse(url) + } + context.startActivity(searchIntent) + }, + onRestart = { + val applicationContext = context.applicationContext + val packageManager = applicationContext.packageManager + val packageName = applicationContext.packageName + + val launchIntent = packageManager.getLaunchIntentForPackage(packageName) + if (launchIntent != null) { + launchIntent.flags = + Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + context.startActivity(launchIntent) + } + } + ) + Stacktrace( + stackTrace = stackTrace + stackTrace + stackTrace, + modifier = Modifier.padding(top = 8.dp) + ) + Spacer(modifier = Modifier.navigationBarsHeight(additional = 8.dp)) + } + } +} + +@Composable +fun PageHeader() { + Text( + stringResource(id = R.string.header_text), + style = MaterialTheme.typography.h4, + modifier = Modifier.padding(vertical = 4.dp), + color = MaterialTheme.colors.onBackground + ) + Spacer(modifier = Modifier.height(4.dp)) + Text( + text = stringResource(id = R.string.explanation_text), + color = MaterialTheme.colors.onBackground + ) +} + +@Composable +fun ExceptionDetails(type: String, message: String, modifier: Modifier) { + Column(modifier = modifier) { + OverlineLabel(label = stringResource(id = R.string.exception_name)) + Text( + text = type, + fontFamily = FontFamily.Monospace, + color = MaterialTheme.colors.onBackground + ) + Spacer(modifier = Modifier.height(8.dp)) + OverlineLabel(label = stringResource(id = R.string.exception_message)) + Text( + text = message, + fontFamily = FontFamily.Monospace, + color = MaterialTheme.colors.onBackground + ) + } +} + +@Composable +fun ExceptionOptions( + onCopy: () -> Unit, + onShare: () -> Unit, + onRestart: () -> Unit, + onSearch: () -> Unit, + modifier: Modifier = Modifier +) { + Column(modifier = modifier) { + OutlinedIconButton( + text = stringResource(id = R.string.copy_stacktrace), + iconId = R.drawable.ic_outline_content_copy_24, + onClick = onCopy, + contentDescription = "Copy", + modifier = Modifier.padding(vertical = 4.dp), + ) + OutlinedIconButton( + text = stringResource(id = R.string.share_stacktrace), + iconId = R.drawable.ic_outline_share_24, + onClick = onShare, + contentDescription = "Share", + modifier = Modifier.padding(vertical = 4.dp) + ) + OutlinedIconButton( + text = stringResource(id = R.string.search_stackoverflow), + iconId = R.drawable.ic_round_search_24, + onClick = onSearch, + contentDescription = "Search Stackoverflow", + modifier = Modifier.padding(vertical = 4.dp) + ) + OutlinedIconButton( + text = stringResource(id = R.string.restart_application), + iconId = R.drawable.ic_baseline_refresh_24, + onClick = onRestart, + contentDescription = "Restart" + ) + } +} + +@Composable +fun Stacktrace(stackTrace: String, modifier: Modifier) { + Column(modifier) { + OverlineLabel(label = stringResource(id = R.string.stacktrace)) + Surface( + color = Color.LightGray.copy(alpha = 0.5f), + modifier = Modifier.padding(top = 4.dp) + ) { + SelectionContainer { + ScrollableText( + text = stackTrace, + style = MaterialTheme.typography.body2.copy(fontSize = 12.sp), + fontFamily = FontFamily.Monospace, + color = MaterialTheme.colors.onBackground, + modifier = Modifier.padding(4.dp) + ) + } + } + } +} + +@Preview +@Composable +fun ExceptionPagePreview() { + WhatTheStackTheme { + ExceptionPage( + type = SampleData.ExceptionType, + message = SampleData.ExceptionMessage, + stackTrace = SampleData.Stacktrace + ) + } +} + +@Preview(uiMode = UI_MODE_NIGHT_YES) +@Composable +fun ExceptionPagePreviewNightMode() { + WhatTheStackTheme { + ExceptionPage( + type = SampleData.ExceptionType, + message = SampleData.ExceptionMessage, + stackTrace = SampleData.Stacktrace + ) + } +} + diff --git a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/preview/SampleData.kt b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/preview/SampleData.kt new file mode 100644 index 0000000..644d892 --- /dev/null +++ b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/preview/SampleData.kt @@ -0,0 +1,32 @@ +package com.haroldadmin.whatthestack.ui.preview + +object SampleData { + const val ExceptionType ="Runtime Exception" + + const val ExceptionMessage = "This exception was thrown purely because it can be thrown" + + const val Stacktrace = + """java.lang.RuntimeException: java.lang.reflect.InvocationTargetException + at com.android.internal.os.RuntimeInitMethodAndArgsCaller.run(RuntimeInit.java:558) + at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) +Caused by: java.lang.reflect.InvocationTargetException + at java.lang.reflect.Method.invoke(Native Method) + at com.android.internal.os.RuntimeInitMethodAndArgsCaller.run(RuntimeInit.java:548) + ... 1 more +Caused by: com.haroldadmin.crashyapp.BecauseICanException: This exception is thrown purely because it can be thrown + at com.haroldadmin.crashyapp.MainActivity.onCreatelambda-0(MainActivity.kt:15) + at com.haroldadmin.crashyapp.MainActivity.r8lambdapFZVHP1EeT4E2LW7TLA5yGBRTTk(Unknown Source:0) + at com.haroldadmin.crashyapp.MainActivityxternalSyntheticLambda0.onClick(Unknown Source:0) + at android.view.View.performClick(View.java:7441) + at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119) + at android.view.View.performClickInternal(View.java:7418) + at android.view.View.access$3700(View.java:835) + at android.view.ViewPerformClick.run(View.java:28676) + at android.os.Handler.handleCallback(Handler.java:938) + at android.os.Handler.dispatchMessage(Handler.java:99) + at android.os.Looper.loopOnce(Looper.java:201) + at android.os.Looper.loop(Looper.java:288) + at android.app.ActivityThread.main(ActivityThread.java:7839) + ... 3 more +""" +} \ No newline at end of file diff --git a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/theme/WhatTheStackTheme.kt b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/theme/WhatTheStackTheme.kt new file mode 100644 index 0000000..79afb05 --- /dev/null +++ b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/theme/WhatTheStackTheme.kt @@ -0,0 +1,38 @@ +package com.haroldadmin.whatthestack.ui.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material.MaterialTheme +import androidx.compose.material.darkColors +import androidx.compose.material.lightColors +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +private val DarkColorPalette = darkColors( + primary = Color(0xffd32f2f), + primaryVariant = Color(0xffff6659), + secondary = Color(0xff616161), + secondaryVariant = Color(0xff373737), +) + +private val LightColorPalette = lightColors( + primary = Color(0xffd32f2f), + primaryVariant = Color(0xff9a0007), + secondary = Color(0xff616161), + secondaryVariant = Color(0x33373737), +) + +internal val SystemBarsColor = Color(0x33373737) + +@Composable +fun WhatTheStackTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + content: @Composable () -> Unit +) { + val colors = if (darkTheme) { + DarkColorPalette + } else { + LightColorPalette + } + + MaterialTheme(colors = colors, content = content) +} \ No newline at end of file diff --git a/what-the-stack/src/main/res/layout/activity_what_the_stack.xml b/what-the-stack/src/main/res/layout/activity_what_the_stack.xml deleted file mode 100644 index 7e85fa7..0000000 --- a/what-the-stack/src/main/res/layout/activity_what_the_stack.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/what-the-stack/src/main/res/values/strings.xml b/what-the-stack/src/main/res/values/strings.xml index 2fecf52..54394d8 100644 --- a/what-the-stack/src/main/res/values/strings.xml +++ b/what-the-stack/src/main/res/values/strings.xml @@ -26,14 +26,13 @@ at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)  - Exception: %1$s - Cause: %1$s + Exception Stacktrace - Message: %1$s - Copy - Share - Restart + Message + Copy Stacktrace + Share Stacktrace + Restart Application Relaunch App Stacktrace copied! - Stackoverflow + Search Stackoverflow \ No newline at end of file From b4ad903e2dbc3de38a7ee88ba3df0fe2ee19b520 Mon Sep 17 00:00:00 2001 From: Kshitij Chauhan Date: Sat, 27 Nov 2021 17:39:52 +0530 Subject: [PATCH 3/9] feat: Migrate sample app to jetpack compose --- .idea/misc.xml | 9 ++++ app/build.gradle | 15 +++++-- app/src/main/AndroidManifest.xml | 2 +- .../com/haroldadmin/crashyapp/MainActivity.kt | 14 +++---- .../crashyapp/ui/pages/HomePage.kt | 41 +++++++++++++++++++ .../crashyapp/ui/theme/CrashyAppTheme.kt | 20 +++++++++ app/src/main/res/layout/activity_main.xml | 32 --------------- app/src/main/res/values/colors.xml | 11 ----- app/src/main/res/values/strings.xml | 3 -- app/src/main/res/values/styles.xml | 11 +---- what-the-stack/build.gradle | 5 --- .../whatthestack/ui/pages/ExceptionPage.kt | 2 +- .../res/drawable/ic_baseline_refresh_24.xml | 3 +- .../drawable/ic_outline_content_copy_24.xml | 3 +- .../main/res/drawable/ic_outline_share_24.xml | 3 +- .../main/res/drawable/ic_round_search_24.xml | 3 +- what-the-stack/src/main/res/values/colors.xml | 12 ------ what-the-stack/src/main/res/values/styles.xml | 12 +----- 18 files changed, 96 insertions(+), 105 deletions(-) create mode 100644 app/src/main/java/com/haroldadmin/crashyapp/ui/pages/HomePage.kt create mode 100644 app/src/main/java/com/haroldadmin/crashyapp/ui/theme/CrashyAppTheme.kt delete mode 100644 app/src/main/res/layout/activity_main.xml delete mode 100644 app/src/main/res/values/colors.xml delete mode 100644 app/src/main/res/values/strings.xml delete mode 100644 what-the-stack/src/main/res/values/colors.xml diff --git a/.idea/misc.xml b/.idea/misc.xml index 09c0d79..99dc872 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -7,6 +7,15 @@ + + + + + + + + + diff --git a/app/build.gradle b/app/build.gradle index e469a44..297b44a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -41,7 +41,11 @@ android { } buildFeatures { - viewBinding true + compose true + } + + composeOptions { + kotlinCompilerExtensionVersion "1.0.5" } } @@ -53,9 +57,12 @@ dependencies { implementation libs.kotlinStdLib implementation libs.appCompat implementation libs.coreKtx - implementation libs.fragmentKtx - implementation libs.constraintLayout - implementation libs.materialComponents + + implementation libs.composeActivity + implementation libs.composeMaterial + implementation libs.composeTooling + implementation libs.accompanistSysUi + implementation libs.accompanistInsets testImplementation libs.junit diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d2e0d1f..b7bfb9e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,7 +5,7 @@ diff --git a/app/src/main/java/com/haroldadmin/crashyapp/MainActivity.kt b/app/src/main/java/com/haroldadmin/crashyapp/MainActivity.kt index 4c890cc..06350b8 100644 --- a/app/src/main/java/com/haroldadmin/crashyapp/MainActivity.kt +++ b/app/src/main/java/com/haroldadmin/crashyapp/MainActivity.kt @@ -1,20 +1,20 @@ package com.haroldadmin.crashyapp import android.os.Bundle +import androidx.activity.compose.setContent import androidx.appcompat.app.AppCompatActivity -import com.haroldadmin.crashyapp.databinding.ActivityMainBinding +import com.haroldadmin.crashyapp.ui.pages.HomePage +import com.haroldadmin.crashyapp.ui.theme.CrashyAppTheme class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - val binding = ActivityMainBinding.inflate(layoutInflater) - setContentView(binding.root) - - binding.crashButton.setOnClickListener { - throw BecauseICanException() + setContent { + CrashyAppTheme { + HomePage() + } } } } -private class BecauseICanException : Exception("This exception is thrown purely because it can be thrown") diff --git a/app/src/main/java/com/haroldadmin/crashyapp/ui/pages/HomePage.kt b/app/src/main/java/com/haroldadmin/crashyapp/ui/pages/HomePage.kt new file mode 100644 index 0000000..d245e77 --- /dev/null +++ b/app/src/main/java/com/haroldadmin/crashyapp/ui/pages/HomePage.kt @@ -0,0 +1,41 @@ +package com.haroldadmin.crashyapp.ui.pages + +import androidx.compose.foundation.layout.* +import androidx.compose.material.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp + +@Composable +fun HomePage() { + Scaffold( + topBar = { + TopAppBar { + Text(text = "Crashy App", style = MaterialTheme.typography.h6) + } + } + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + modifier = Modifier + .padding(8.dp) + .fillMaxWidth() + .fillMaxHeight() + ) { + Text( + text = "Press the button below to see error screen from WhatTheStack!", + textAlign = TextAlign.Center + ) + Spacer(modifier = Modifier.height(16.dp)) + Button(onClick = { throw BecauseICanException() }) { + Text(text = "Crash!") + } + } + } +} + +private class BecauseICanException : + Exception("This exception is thrown purely because it can be thrown") diff --git a/app/src/main/java/com/haroldadmin/crashyapp/ui/theme/CrashyAppTheme.kt b/app/src/main/java/com/haroldadmin/crashyapp/ui/theme/CrashyAppTheme.kt new file mode 100644 index 0000000..9a1b2c6 --- /dev/null +++ b/app/src/main/java/com/haroldadmin/crashyapp/ui/theme/CrashyAppTheme.kt @@ -0,0 +1,20 @@ +package com.haroldadmin.crashyapp.ui.theme + +import androidx.compose.material.MaterialTheme +import androidx.compose.material.lightColors +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +private val ColorPalette = lightColors( + primary = Color(0xffd32f2f), + primaryVariant = Color(0xff9a0007), + secondary = Color(0xff616161), + secondaryVariant = Color(0x33373737), +) + +@Composable +fun CrashyAppTheme( + content: @Composable () -> Unit +) { + MaterialTheme(colors = ColorPalette, content = content) +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index 0131968..0000000 --- a/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml deleted file mode 100644 index f12742b..0000000 --- a/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - #d32f2f - #ff6659 - #9a0007 - #616161 - #8e8e8e - #373737 - #ffffff - #ffffff - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml deleted file mode 100644 index d1882f5..0000000 --- a/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - Crashy App - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 05ba9fc..f3f0b8f 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,13 +1,4 @@ - - - diff --git a/what-the-stack/build.gradle b/what-the-stack/build.gradle index c6d3657..8b8feb6 100644 --- a/what-the-stack/build.gradle +++ b/what-the-stack/build.gradle @@ -36,7 +36,6 @@ android { } buildFeatures { - viewBinding true compose true } @@ -51,11 +50,7 @@ dependencies { implementation libs.kotlinStdLib implementation libs.appCompat implementation libs.coreKtx - implementation libs.fragmentKtx - implementation libs.constraintLayout - implementation libs.materialComponents implementation libs.startup - implementation libs.insetter implementation libs.composeActivity implementation libs.composeMaterial diff --git a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/pages/ExceptionPage.kt b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/pages/ExceptionPage.kt index 71c310c..955e62a 100644 --- a/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/pages/ExceptionPage.kt +++ b/what-the-stack/src/main/java/com/haroldadmin/whatthestack/ui/pages/ExceptionPage.kt @@ -100,7 +100,7 @@ fun ExceptionPage( } ) Stacktrace( - stackTrace = stackTrace + stackTrace + stackTrace, + stackTrace = stackTrace, modifier = Modifier.padding(top = 8.dp) ) Spacer(modifier = Modifier.navigationBarsHeight(additional = 8.dp)) diff --git a/what-the-stack/src/main/res/drawable/ic_baseline_refresh_24.xml b/what-the-stack/src/main/res/drawable/ic_baseline_refresh_24.xml index f2be45b..5ab492c 100644 --- a/what-the-stack/src/main/res/drawable/ic_baseline_refresh_24.xml +++ b/what-the-stack/src/main/res/drawable/ic_baseline_refresh_24.xml @@ -2,8 +2,7 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/what-the-stack/src/main/res/drawable/ic_outline_content_copy_24.xml b/what-the-stack/src/main/res/drawable/ic_outline_content_copy_24.xml index 79c5a76..eb384e5 100644 --- a/what-the-stack/src/main/res/drawable/ic_outline_content_copy_24.xml +++ b/what-the-stack/src/main/res/drawable/ic_outline_content_copy_24.xml @@ -2,8 +2,7 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorOnPrimary"> + android:viewportHeight="24"> diff --git a/what-the-stack/src/main/res/drawable/ic_outline_share_24.xml b/what-the-stack/src/main/res/drawable/ic_outline_share_24.xml index 3a6a059..394e3ef 100644 --- a/what-the-stack/src/main/res/drawable/ic_outline_share_24.xml +++ b/what-the-stack/src/main/res/drawable/ic_outline_share_24.xml @@ -2,8 +2,7 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/what-the-stack/src/main/res/drawable/ic_round_search_24.xml b/what-the-stack/src/main/res/drawable/ic_round_search_24.xml index c1818d5..b86e6fc 100644 --- a/what-the-stack/src/main/res/drawable/ic_round_search_24.xml +++ b/what-the-stack/src/main/res/drawable/ic_round_search_24.xml @@ -2,8 +2,7 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="24"> diff --git a/what-the-stack/src/main/res/values/colors.xml b/what-the-stack/src/main/res/values/colors.xml deleted file mode 100644 index 9f135e1..0000000 --- a/what-the-stack/src/main/res/values/colors.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - #d32f2f - #ff6659 - #9a0007 - #616161 - #8e8e8e - #373737 - #33373737 - #ffffff - #ffffff - \ No newline at end of file diff --git a/what-the-stack/src/main/res/values/styles.xml b/what-the-stack/src/main/res/values/styles.xml index 98b8f55..0870988 100644 --- a/what-the-stack/src/main/res/values/styles.xml +++ b/what-the-stack/src/main/res/values/styles.xml @@ -1,14 +1,4 @@ - +