From 33abcf4cbbfe5b0bc5837116003fd3b30293b7c6 Mon Sep 17 00:00:00 2001 From: Infi Date: Sat, 3 Feb 2024 13:22:27 +0100 Subject: [PATCH] feat(gp): rm feedback and analysis Signed-off-by: Infi --- app/build.gradle | 4 - .../chat/revolt/activities/MainActivity.kt | 3 - .../main/java/chat/revolt/api/RevoltAPI.kt | 2 +- .../screens/chat/dialogs/FeedbackDialog.kt | 280 ------------------ .../revolt/screens/settings/SettingsScreen.kt | 20 +- .../res/drawable/ic_comment_quote_24dp.xml | 9 + app/src/main/res/values/strings.xml | 16 +- revoltbuild.properties.example | 2 - 8 files changed, 29 insertions(+), 307 deletions(-) delete mode 100644 app/src/main/java/chat/revolt/screens/chat/dialogs/FeedbackDialog.kt create mode 100644 app/src/main/res/drawable/ic_comment_quote_24dp.xml diff --git a/app/build.gradle b/app/build.gradle index 4303f0a0..54e0d699 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -114,8 +114,6 @@ android { shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' buildConfigField "String", "SENTRY_DSN", "\"${buildproperty('sentry.dsn', 'RVX_SENTRY_DSN')}\"" - buildConfigField "Boolean", "ANALYSIS_ENABLED", "${buildproperty('analysis.enabled', 'RVX_ANALYSIS_ENABLED')}" - buildConfigField "String", "ANALYSIS_BASEURL", "\"${buildproperty('analysis.base_url', 'RVX_ANALYSIS_BASEURL')}\"" } debug { @@ -126,8 +124,6 @@ android { resValue "string", "app_name", buildproperty('build.debug.app_name', 'RVX_DEBUG_APP_NAME') buildConfigField "String", "SENTRY_DSN", "\"${buildproperty('sentry.dsn', 'RVX_SENTRY_DSN')}\"" - buildConfigField "Boolean", "ANALYSIS_ENABLED", "${buildproperty('analysis.enabled', 'RVX_ANALYSIS_ENABLED')}" - buildConfigField "String", "ANALYSIS_BASEURL", "\"${buildproperty('analysis.base_url', 'RVX_ANALYSIS_BASEURL')}\"" } } compileOptions { diff --git a/app/src/main/java/chat/revolt/activities/MainActivity.kt b/app/src/main/java/chat/revolt/activities/MainActivity.kt index 7267e8db..a60ba71d 100644 --- a/app/src/main/java/chat/revolt/activities/MainActivity.kt +++ b/app/src/main/java/chat/revolt/activities/MainActivity.kt @@ -35,7 +35,6 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable -import androidx.navigation.compose.dialog import androidx.navigation.compose.rememberNavController import chat.revolt.BuildConfig import chat.revolt.R @@ -52,7 +51,6 @@ import chat.revolt.screens.SplashScreen import chat.revolt.screens.about.AboutScreen import chat.revolt.screens.about.AttributionScreen import chat.revolt.screens.chat.ChatRouterScreen -import chat.revolt.screens.chat.dialogs.FeedbackDialog import chat.revolt.screens.labs.LabsRootScreen import chat.revolt.screens.login.LoginGreetingScreen import chat.revolt.screens.login.LoginScreen @@ -375,7 +373,6 @@ fun AppEntrypoint( composable("settings/appearance") { AppearanceSettingsScreen(navController) } composable("settings/debug") { DebugSettingsScreen(navController) } composable("settings/changelogs") { ChangelogsSettingsScreen(navController) } - dialog("settings/feedback") { FeedbackDialog(navController) } composable("about") { AboutScreen(navController) } composable("about/oss") { AttributionScreen(navController) } diff --git a/app/src/main/java/chat/revolt/api/RevoltAPI.kt b/app/src/main/java/chat/revolt/api/RevoltAPI.kt index afc043b0..0b6da651 100644 --- a/app/src/main/java/chat/revolt/api/RevoltAPI.kt +++ b/app/src/main/java/chat/revolt/api/RevoltAPI.kt @@ -52,7 +52,7 @@ const val REVOLT_INVITES = "https://rvlt.gg" const val REVOLT_WEBSOCKET = "wss://ws.revolt.chat" fun buildUserAgent(accessMethod: String = "Ktor"): String { - return "$accessMethod RevoltAndroid/${BuildConfig.VERSION_NAME} ${BuildConfig.APPLICATION_ID} (Android ${android.os.Build.VERSION.SDK_INT}; ${android.os.Build.MANUFACTURER} ${android.os.Build.DEVICE}; Analysis ${BuildConfig.ANALYSIS_ENABLED} ${BuildConfig.ANALYSIS_BASEURL}; (Kotlin ${KotlinVersion.CURRENT})" + return "$accessMethod RevoltAndroid/${BuildConfig.VERSION_NAME} ${BuildConfig.APPLICATION_ID} (Android ${android.os.Build.VERSION.SDK_INT}; ${android.os.Build.MANUFACTURER} ${android.os.Build.DEVICE}; (Kotlin ${KotlinVersion.CURRENT})" } private const val BACKEND_IS_STABLE = false diff --git a/app/src/main/java/chat/revolt/screens/chat/dialogs/FeedbackDialog.kt b/app/src/main/java/chat/revolt/screens/chat/dialogs/FeedbackDialog.kt deleted file mode 100644 index d8d9e62a..00000000 --- a/app/src/main/java/chat/revolt/screens/chat/dialogs/FeedbackDialog.kt +++ /dev/null @@ -1,280 +0,0 @@ -package chat.revolt.screens.chat.dialogs - -import android.util.Log -import android.widget.Toast -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowDropDown -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.DropdownMenu -import androidx.compose.material3.DropdownMenuItem -import androidx.compose.material3.Icon -import androidx.compose.material3.IconToggleButton -import androidx.compose.material3.Text -import androidx.compose.material3.TextButton -import androidx.compose.material3.TextField -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.navigation.NavController -import chat.revolt.BuildConfig -import chat.revolt.R -import chat.revolt.api.REVOLT_BASE -import chat.revolt.api.RevoltAPI -import chat.revolt.api.RevoltHttp -import chat.revolt.components.generic.FormTextField -import io.ktor.client.request.post -import io.ktor.client.request.setBody -import io.ktor.client.statement.bodyAsText -import io.ktor.http.ContentType -import io.ktor.http.contentType -import kotlinx.coroutines.launch -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -enum class FeedbackType(val value: String) { - Satisfaction("satisfaction"), - FeatureRequest("featurerequest"), - BugReport("bug"), - UxFeedback("ux"), - Performance("performance"), - Security("security"), - Other("other") -} - -@Serializable -data class FeedbackBody( - val type: String, - val message: String, - @SerialName("api_host") - val apiHost: String, - @SerialName("app_id") - val appId: String, - @SerialName("app_version") - val appVersion: String, - @SerialName("app_build") - val appBuild: String, - @SerialName("android_api") - val androidApi: String, - @SerialName("android_device") - val androidDevice: String, - @SerialName("android_manufacturer") - val androidManufacturer: String, - @SerialName("id_for_spam_protection_pls_dont_spam_but_if_you_do_i_will_know") - val author: String -) - -suspend fun sendFeedback(type: FeedbackType, message: String): String { - val response = RevoltHttp.post("${BuildConfig.ANALYSIS_BASEURL}/api/feedback/android") { - setBody( - FeedbackBody( - type = type.value, - message = message, - apiHost = REVOLT_BASE, - appId = BuildConfig.APPLICATION_ID, - appVersion = BuildConfig.VERSION_NAME, - appBuild = BuildConfig.VERSION_CODE.toString(), - androidApi = android.os.Build.VERSION.SDK_INT.toString(), - androidDevice = android.os.Build.DEVICE, - androidManufacturer = android.os.Build.MANUFACTURER, - author = RevoltAPI.selfId ?: "RevoltAPI.selfId is null" - ) - ) - contentType(ContentType.Application.Json) - } - - Log.d("FeedbackDialog", "Feedback sent: ${response.bodyAsText()}") - - return response.bodyAsText() -} - -@Composable -fun FeedbackDialog(navController: NavController) { - if (!BuildConfig.ANALYSIS_ENABLED) { - AlertDialog(onDismissRequest = { - navController.popBackStack() - }, title = { - Text( - text = stringResource(id = R.string.settings_feedback_disabled_title), - modifier = Modifier.fillMaxWidth() - ) - }, text = { - Text( - text = stringResource( - id = R.string.settings_feedback_disabled_message, - BuildConfig.VERSION_NAME, - BuildConfig.BUILD_TYPE - ) - ) - }, confirmButton = { - TextButton(onClick = { - navController.popBackStack() - }) { - Text(text = stringResource(id = R.string.ok)) - } - }) - return - } - - val category = mapOf( - FeedbackType.Satisfaction to stringResource(R.string.settings_feedback_category_satisfaction), - FeedbackType.FeatureRequest to stringResource(R.string.settings_feedback_category_feature), - FeedbackType.BugReport to stringResource(R.string.settings_feedback_category_bug), - FeedbackType.UxFeedback to stringResource(R.string.settings_feedback_category_ux), - FeedbackType.Performance to stringResource(R.string.settings_feedback_category_performance), - FeedbackType.Security to stringResource(R.string.settings_feedback_category_security), - FeedbackType.Other to stringResource(R.string.settings_feedback_category_other) - ) - val categoryDropdownExpanded = remember { mutableStateOf(false) } - val categoryDropdownSelected = remember { mutableStateOf(FeedbackType.Satisfaction) } - val message = remember { mutableStateOf("") } - val error = remember { mutableStateOf("") } - val sending = remember { mutableStateOf(false) } - - val scope = rememberCoroutineScope() - val context = LocalContext.current - - AlertDialog( - onDismissRequest = { - navController.popBackStack() - }, - title = { - Text( - text = stringResource(id = R.string.settings_feedback), - modifier = Modifier.fillMaxWidth() - ) - }, - text = { - Column { - Text( - text = stringResource(id = R.string.settings_feedback_introduction) - ) - Spacer(modifier = Modifier.height(16.dp)) - - Box { - TextField( - value = category[categoryDropdownSelected.value] - ?: stringResource(id = R.string.unknown), - onValueChange = {}, - label = { - Text( - text = stringResource(id = R.string.settings_feedback_category) - ) - }, - readOnly = true, - trailingIcon = { - IconToggleButton( - checked = categoryDropdownExpanded.value, - onCheckedChange = { - categoryDropdownExpanded.value = it - } - ) { - Icon( - imageVector = Icons.Default.ArrowDropDown, - contentDescription = stringResource( - id = R.string.settings_feedback_category - ) - ) - } - }, - modifier = Modifier.fillMaxWidth() - ) - - DropdownMenu( - expanded = categoryDropdownExpanded.value, - onDismissRequest = { - categoryDropdownExpanded.value = false - } - ) { - category.forEach { (key, value) -> - DropdownMenuItem( - text = { - Text(text = value) - }, - onClick = { - categoryDropdownSelected.value = key - categoryDropdownExpanded.value = false - } - ) - } - } - } - - Spacer(modifier = Modifier.height(16.dp)) - - FormTextField( - value = message.value, - label = stringResource(id = R.string.settings_feedback_message), - onChange = { - message.value = it - }, - supportingText = { - Text( - text = "${message.value.length}/1250" - ) - }, - enabled = !sending.value, - singleLine = false, - modifier = Modifier.fillMaxWidth() - ) - } - }, - dismissButton = { - TextButton( - onClick = { - navController.popBackStack() - }, - modifier = Modifier.testTag("feedback_cancel"), - enabled = !sending.value - ) { - Text(text = stringResource(id = R.string.cancel)) - } - }, - confirmButton = { - TextButton( - onClick = { - if (message.value.length > 1250) { - error.value = - context.getString(R.string.settings_feedback_message_too_long, 1250) - } else { - error.value = "" - sending.value = true - scope.launch { - try { - val result = - sendFeedback(categoryDropdownSelected.value, message.value) - Log.d("FeedbackDialog", "Feedback sent with result: $result") - - if (result.isBlank()) { - navController.popBackStack() - } else { - error.value = result - Toast.makeText(context, error.value, Toast.LENGTH_SHORT).show() - } - } catch (e: Exception) { - Log.e("FeedbackDialog", "Error sending feedback", e) - error.value = context.getString(R.string.settings_feedback_error) - } finally { - sending.value = false - } - } - } - }, - enabled = !sending.value && message.value.isNotBlank(), - modifier = Modifier.testTag("feedback_submit") - ) { - Text(text = stringResource(id = R.string.report_submit)) - } - } - ) -} diff --git a/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt b/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt index 664f4486..4fc751ab 100644 --- a/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt +++ b/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt @@ -1,5 +1,6 @@ package chat.revolt.screens.settings +import android.content.Intent import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -28,16 +29,19 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import androidx.core.net.toUri import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.ViewModel import androidx.navigation.NavController import chat.revolt.BuildConfig import chat.revolt.R +import chat.revolt.activities.InviteActivity import chat.revolt.api.RevoltAPI import chat.revolt.api.settings.FeatureFlags import chat.revolt.api.settings.GlobalState @@ -68,6 +72,7 @@ fun SettingsScreen( navController: NavController, viewModel: SettingsScreenViewModel = hiltViewModel() ) { + val context = LocalContext.current val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior() Scaffold( @@ -274,16 +279,27 @@ fun SettingsScreen( text = stringResource(id = R.string.settings_feedback) ) }, + supportingContent = { + Text( + text = stringResource(id = R.string.settings_feedback_description) + ) + }, leadingContent = { Icon( - imageVector = Icons.Default.ArrowForward, + painter = painterResource(R.drawable.ic_comment_quote_24dp), contentDescription = null, ) }, modifier = Modifier .testTag("settings_view_feedback") .clickable { - navController.navigate("settings/feedback") + val intent = Intent( + context, + InviteActivity::class.java + ).setAction(Intent.ACTION_VIEW) + + intent.data = "https://rvlt.gg/Testers".toUri() + context.startActivity(intent) } ) diff --git a/app/src/main/res/drawable/ic_comment_quote_24dp.xml b/app/src/main/res/drawable/ic_comment_quote_24dp.xml new file mode 100644 index 00000000..c8af558f --- /dev/null +++ b/app/src/main/res/drawable/ic_comment_quote_24dp.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dddb315c..58b9b896 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -528,21 +528,7 @@ This file is not a valid colour override file. Feedback - Any feedback you have for Revolt is greatly appreciated and all feedback is read by the development team of our Android app. - Category - General-purpose feedback - Feature request - Bug report - User experience (UI/UX) - Performance - Security - Other - Message - Message is too long. Please shorten it to %1$d characters or less. - An error occurred while sending your feedback. Please try again later. - - Feedback unavailable - Feedback is not available on this build of Revolt. Support for this build is limited. (Build: %1$s %2$s) + Join the Revolt server to give feedback or suggestions and report bugs. Changelogs What\'s been cooking ✨ diff --git a/revoltbuild.properties.example b/revoltbuild.properties.example index e2ccb724..b3071f3a 100644 --- a/revoltbuild.properties.example +++ b/revoltbuild.properties.example @@ -1,5 +1,3 @@ sentry.dsn= sentry.upload_mappings=true -analysis.enabled=false -analysis.base_url= build.debug.app_name= \ No newline at end of file