feat: error analysis

This commit is contained in:
Infi 2023-03-05 06:05:35 +01:00
parent 249de62988
commit 4c1e7d8e61
17 changed files with 124 additions and 37 deletions

2
.gitignore vendored
View File

@ -14,3 +14,5 @@
.externalNativeBuild .externalNativeBuild
.cxx .cxx
local.properties local.properties
revoltbuild.properties
sentry.properties

View File

@ -4,10 +4,26 @@ plugins {
id 'org.jetbrains.kotlin.plugin.serialization' id 'org.jetbrains.kotlin.plugin.serialization'
id 'com.mikepenz.aboutlibraries.plugin' id 'com.mikepenz.aboutlibraries.plugin'
id 'com.google.dagger.hilt.android' id 'com.google.dagger.hilt.android'
id "io.sentry.android.gradle" version "3.4.2"
id 'kotlin-kapt' id 'kotlin-kapt'
} }
def property(String fileName, String propertyName) {
def propsFile = rootProject.file(fileName)
if (propsFile.exists()) {
def props = new Properties()
props.load(new FileInputStream(propsFile))
if (props[propertyName] != null) {
return props[propertyName]
} else {
throw new GradleException("'" + propertyName + "' not found in '" + fileName + "'")
}
} else {
throw new GradleException("'" + fileName + "' not found in app/, please create it from '" + fileName + ".example'")
}
}
android { android {
compileSdk 33 compileSdk 33
@ -29,6 +45,11 @@ android {
minifyEnabled true minifyEnabled true
shrinkResources true shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField "String", "SENTRY_DSN", "\"${property('revoltbuild.properties', 'sentry.dsn')}\""
}
debug {
buildConfigField "String", "SENTRY_DSN", "\"${property('revoltbuild.properties', 'sentry.dsn')}\""
} }
} }
compileOptions { compileOptions {

View File

@ -16,6 +16,9 @@
android:name=".RevoltApplication" android:name=".RevoltApplication"
android:theme="@style/Theme.Revolt" android:theme="@style/Theme.Revolt"
tools:targetApi="31"> tools:targetApi="31">
<meta-data
android:name="io.sentry.auto-init"
android:value="false" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"

View File

@ -30,11 +30,20 @@ import com.google.accompanist.navigation.animation.AnimatedNavHost
import com.google.accompanist.navigation.animation.composable import com.google.accompanist.navigation.animation.composable
import com.google.accompanist.navigation.animation.rememberAnimatedNavController import com.google.accompanist.navigation.animation.rememberAnimatedNavController
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import io.sentry.android.core.SentryAndroid
@AndroidEntryPoint @AndroidEntryPoint
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
SentryAndroid.init(this) { options ->
options.dsn = BuildConfig.SENTRY_DSN
options.isDebug = BuildConfig.DEBUG
options.environment = BuildConfig.BUILD_TYPE
options.release = BuildConfig.VERSION_NAME
}
setContent { setContent {
AppEntrypoint() AppEntrypoint()
} }

View File

@ -21,6 +21,7 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
@ -111,6 +112,7 @@ fun MessageField(
onAddAttachment() onAddAttachment()
} }
.padding(4.dp) .padding(4.dp)
.testTag("add_attachment")
) )
}, },
trailingIcon = { trailingIcon = {
@ -132,6 +134,7 @@ fun MessageField(
.size(32.dp) .size(32.dp)
.clickable { onSendMessage() } .clickable { onSendMessage() }
.padding(4.dp) .padding(4.dp)
.testTag("send_message")
) )
} }
} }

View File

@ -23,9 +23,10 @@ import androidx.compose.ui.unit.dp
fun SheetClickable( fun SheetClickable(
icon: @Composable (Modifier) -> Unit, icon: @Composable (Modifier) -> Unit,
label: @Composable (TextStyle) -> Unit, label: @Composable (TextStyle) -> Unit,
modifier: Modifier = Modifier,
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
Box(modifier = Modifier.padding(vertical = 4.dp)) { Box(modifier = modifier.padding(vertical = 4.dp)) {
Row( Row(
modifier = Modifier modifier = Modifier
.clip(MaterialTheme.shapes.medium) .clip(MaterialTheme.shapes.medium)

View File

@ -12,6 +12,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ClipboardManager import androidx.compose.ui.platform.ClipboardManager
import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -173,7 +174,9 @@ fun AboutScreen(
) { ) {
ElevatedButton( ElevatedButton(
onClick = { navController.navigate("about/oss") }, onClick = { navController.navigate("about/oss") },
modifier = Modifier.fillMaxWidth() modifier = Modifier
.fillMaxWidth()
.testTag("view_oss_attribution")
) { ) {
Text(text = stringResource(id = R.string.oss_attribution)) Text(text = stringResource(id = R.string.oss_attribution))
} }

View File

@ -14,6 +14,7 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@ -185,16 +186,22 @@ fun ReportMessageDialog(
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = { TextButton(
navController.popBackStack() onClick = {
}) { navController.popBackStack()
},
modifier = Modifier.testTag("report_cancel")
) {
Text(text = stringResource(id = R.string.report_cancel)) Text(text = stringResource(id = R.string.report_cancel))
} }
}, },
confirmButton = { confirmButton = {
TextButton(onClick = { TextButton(
state.value = ReportingState.Sending onClick = {
}) { state.value = ReportingState.Sending
},
modifier = Modifier.testTag("report_send")
) {
Text(text = stringResource(id = R.string.report_submit)) Text(text = stringResource(id = R.string.report_submit))
} }
} }
@ -284,19 +291,25 @@ fun ReportMessageDialog(
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = { TextButton(
navController.popBackStack() onClick = {
}) { navController.popBackStack()
},
modifier = Modifier.testTag("report_block_no")
) {
Text(text = stringResource(id = R.string.report_block_no)) Text(text = stringResource(id = R.string.report_block_no))
} }
}, },
confirmButton = { confirmButton = {
TextButton(onClick = { TextButton(
scope.launch { onClick = {
blockUser(message.author ?: return@launch) scope.launch {
} blockUser(message.author ?: return@launch)
navController.popBackStack() }
}) { navController.popBackStack()
},
modifier = Modifier.testTag("report_block_yes")
) {
Text(text = stringResource(id = R.string.report_block_yes)) Text(text = stringResource(id = R.string.report_block_yes))
} }
} }
@ -331,9 +344,12 @@ fun ReportMessageDialog(
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = { TextButton(
navController.popBackStack() onClick = {
}) { navController.popBackStack()
},
modifier = Modifier.testTag("report_error_ok")
) {
Text(text = stringResource(id = R.string.ok)) Text(text = stringResource(id = R.string.ok))
} }
}, },

View File

@ -8,6 +8,7 @@ import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
@ -53,14 +54,17 @@ fun HomeScreen(navController: NavController, viewModel: HomeScreenViewModel = hi
inclusive = true inclusive = true
} }
} }
}) },
modifier = Modifier.testTag("logout_from_home")
)
LinkOnHome( LinkOnHome(
heading = stringResource(id = R.string.settings), heading = stringResource(id = R.string.settings),
icon = Icons.Default.Settings, icon = Icons.Default.Settings,
onClick = { onClick = {
navController.navigate("settings") navController.navigate("settings")
}) }
)
Text(buildAnnotatedString { Text(buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append("Note: ") append("Note: ")

View File

@ -14,6 +14,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
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 androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -103,14 +104,18 @@ fun GreeterScreen(navController: NavController) {
) { ) {
ElevatedButton( ElevatedButton(
onClick = { navController.navigate("about/placeholder") }, onClick = { navController.navigate("about/placeholder") },
modifier = Modifier.fillMaxWidth() modifier = Modifier
.fillMaxWidth()
.testTag("view_signup_page_button")
) { ) {
Text(text = stringResource(R.string.signup)) Text(text = stringResource(R.string.signup))
} }
Button( Button(
onClick = { navController.navigate("login/login") }, onClick = { navController.navigate("login/login") },
modifier = Modifier.fillMaxWidth() modifier = Modifier
.fillMaxWidth()
.testTag("view_login_page_button")
) { ) {
Text(text = stringResource(R.string.login)) Text(text = stringResource(R.string.login))
} }

View File

@ -9,6 +9,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
@ -205,24 +206,31 @@ fun LoginScreen(
Weblink( Weblink(
text = stringResource(R.string.password_manager_hint), text = stringResource(R.string.password_manager_hint),
url = "$REVOLT_SUPPORT/kb/interface/android/using-a-password-manager", url = "$REVOLT_SUPPORT/kb/interface/android/using-a-password-manager",
modifier = Modifier.testTag("password_manager_kb_link")
) )
AnyLink( AnyLink(
text = stringResource(R.string.resend_verification), text = stringResource(R.string.resend_verification),
action = { navController.navigate("about/placeholder") }, action = { navController.navigate("about/placeholder") },
modifier = Modifier.padding(vertical = 7.dp) modifier = Modifier
.padding(vertical = 7.dp)
.testTag("resend_verification_link")
) )
ElevatedButton( ElevatedButton(
onClick = { navController.popBackStack() }, onClick = { navController.popBackStack() },
modifier = Modifier.fillMaxWidth() modifier = Modifier
.fillMaxWidth()
.testTag("exit_login_page_button")
) { ) {
Text(text = stringResource(R.string.back)) Text(text = stringResource(R.string.back))
} }
Button( Button(
onClick = { viewModel.doLogin() }, onClick = { viewModel.doLogin() },
modifier = Modifier.fillMaxWidth() modifier = Modifier
.fillMaxWidth()
.testTag("do_login_button")
) { ) {
Text(text = stringResource(R.string.login)) Text(text = stringResource(R.string.login))
} }

View File

@ -11,6 +11,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
@ -225,6 +226,7 @@ fun MfaScreen(
modifier = Modifier modifier = Modifier
.padding(horizontal = 20.dp, vertical = 10.dp) .padding(horizontal = 20.dp, vertical = 10.dp)
.fillMaxWidth() .fillMaxWidth()
.testTag("do_totp_button")
) { ) {
Text( Text(
text = stringResource(R.string.next), text = stringResource(R.string.next),
@ -264,6 +266,7 @@ fun MfaScreen(
modifier = Modifier modifier = Modifier
.padding(horizontal = 20.dp, vertical = 10.dp) .padding(horizontal = 20.dp, vertical = 10.dp)
.fillMaxWidth() .fillMaxWidth()
.testTag("do_mfa_recovery_button")
) { ) {
Text( Text(
text = stringResource(R.string.next), text = stringResource(R.string.next),

View File

@ -14,6 +14,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
@ -83,7 +84,7 @@ fun AppearanceSettingsScreen(
color = Color(0xff1c243c), color = Color(0xff1c243c),
text = stringResource(id = R.string.settings_appearance_theme_revolt), text = stringResource(id = R.string.settings_appearance_theme_revolt),
selected = GlobalState.theme == Theme.Revolt, selected = GlobalState.theme == Theme.Revolt,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f).testTag("set_theme_revolt"),
) { ) {
setNewTheme(Theme.Revolt) setNewTheme(Theme.Revolt)
} }
@ -92,7 +93,7 @@ fun AppearanceSettingsScreen(
color = Color(0xfff7f7f7), color = Color(0xfff7f7f7),
text = stringResource(id = R.string.settings_appearance_theme_light), text = stringResource(id = R.string.settings_appearance_theme_light),
selected = GlobalState.theme == Theme.Light, selected = GlobalState.theme == Theme.Light,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f).testTag("set_theme_light"),
) { ) {
setNewTheme(Theme.Light) setNewTheme(Theme.Light)
} }
@ -101,7 +102,7 @@ fun AppearanceSettingsScreen(
color = Color(0xff000000), color = Color(0xff000000),
text = stringResource(id = R.string.settings_appearance_theme_amoled), text = stringResource(id = R.string.settings_appearance_theme_amoled),
selected = GlobalState.theme == Theme.Amoled, selected = GlobalState.theme == Theme.Amoled,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f).testTag("set_theme_amoled"),
) { ) {
setNewTheme(Theme.Amoled) setNewTheme(Theme.Amoled)
} }
@ -110,7 +111,7 @@ fun AppearanceSettingsScreen(
color = if (isSystemInDarkTheme()) Color(0xff1c243c) else Color(0xfff7f7f7), color = if (isSystemInDarkTheme()) Color(0xff1c243c) else Color(0xfff7f7f7),
text = stringResource(id = R.string.settings_appearance_theme_none), text = stringResource(id = R.string.settings_appearance_theme_none),
selected = GlobalState.theme == Theme.None, selected = GlobalState.theme == Theme.None,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f).testTag("set_theme_none"),
) { ) {
setNewTheme(Theme.None) setNewTheme(Theme.None)
} }
@ -120,7 +121,7 @@ fun AppearanceSettingsScreen(
color = dynamicDarkColorScheme(LocalContext.current).primary, color = dynamicDarkColorScheme(LocalContext.current).primary,
text = stringResource(id = R.string.settings_appearance_theme_m3dynamic), text = stringResource(id = R.string.settings_appearance_theme_m3dynamic),
selected = GlobalState.theme == Theme.M3Dynamic, selected = GlobalState.theme == Theme.M3Dynamic,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f).testTag("set_theme_m3dynamic"),
) { ) {
setNewTheme(Theme.M3Dynamic) setNewTheme(Theme.M3Dynamic)
} }
@ -129,7 +130,7 @@ fun AppearanceSettingsScreen(
color = Color(0xffa0a0a0), color = Color(0xffa0a0a0),
text = stringResource(id = R.string.settings_appearance_theme_m3dynamic_unsupported), text = stringResource(id = R.string.settings_appearance_theme_m3dynamic_unsupported),
selected = false, selected = false,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f).testTag("set_theme_m3dynamic_unsupported"),
) { ) {
Toast.makeText( Toast.makeText(
context, context,

View File

@ -9,6 +9,7 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
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 androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -51,8 +52,9 @@ fun SettingsScreen(
text = stringResource(id = R.string.settings_appearance), text = stringResource(id = R.string.settings_appearance),
style = textStyle style = textStyle
) )
}) },
{ modifier = Modifier.testTag("settings_view_appearance")
) {
navController.navigate("settings/appearance") navController.navigate("settings/appearance")
} }
@ -66,8 +68,9 @@ fun SettingsScreen(
}, },
label = { textStyle -> label = { textStyle ->
Text(text = stringResource(id = R.string.about), style = textStyle) Text(text = stringResource(id = R.string.about), style = textStyle)
}) },
{ modifier = Modifier.testTag("settings_view_about")
) {
navController.navigate("about") navController.navigate("about")
} }
} }

0
gradlew vendored Normal file → Executable file
View File

View File

@ -0,0 +1 @@
sentry.dsn=

View File

@ -0,0 +1,4 @@
defaults.url=https://sentry.actual.tld
defaults.project=not-revolt
defaults.org=generic-chat-platform-inc
auth.token=