From 9cda091d03917a7da504145e93c362e7cb801bb5 Mon Sep 17 00:00:00 2001 From: Nik Clayton Date: Thu, 3 Aug 2023 12:20:35 +0200 Subject: [PATCH] Show additional bug report info in AboutActivity (#3802) Make it easier for people to find information we need for a bug report, and show it on AboutActivity. New info is: - Device manufacturer (e.g., "Google") and model (e.g., "Pixel 4a (5G)") - Android version (e.g., "13") - SDK version (e.g., "33") - Active account (e.g., "@Tusky@mastodon.social") - Server's version (e.g., "4.1.2+nightly-20230627") All info is copyable to make it easy to include in a bug report. A button to copy the information is also shown. --- .../com/keylesspalace/tusky/AboutActivity.kt | 44 +++++ .../components/instanceinfo/InstanceInfo.kt | 3 +- .../instanceinfo/InstanceInfoRepository.kt | 3 +- .../main/res/drawable/ic_content_copy_24.xml | 5 + app/src/main/res/layout/activity_about.xml | 158 ++++++++++++++---- app/src/main/res/values/strings.xml | 16 +- 6 files changed, 183 insertions(+), 46 deletions(-) create mode 100644 app/src/main/res/drawable/ic_content_copy_24.xml diff --git a/app/src/main/java/com/keylesspalace/tusky/AboutActivity.kt b/app/src/main/java/com/keylesspalace/tusky/AboutActivity.kt index 7c2eedccd..b8b64692e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/AboutActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/AboutActivity.kt @@ -1,6 +1,10 @@ package com.keylesspalace.tusky +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context import android.content.Intent +import android.os.Build import android.os.Bundle import android.text.SpannableString import android.text.SpannableStringBuilder @@ -8,13 +12,21 @@ import android.text.method.LinkMovementMethod import android.text.style.URLSpan import android.text.util.Linkify import android.widget.TextView +import android.widget.Toast import androidx.annotation.StringRes +import androidx.lifecycle.lifecycleScope +import com.keylesspalace.tusky.components.instanceinfo.InstanceInfoRepository import com.keylesspalace.tusky.databinding.ActivityAboutBinding import com.keylesspalace.tusky.di.Injectable import com.keylesspalace.tusky.util.NoUnderlineURLSpan import com.keylesspalace.tusky.util.hide +import com.keylesspalace.tusky.util.show +import kotlinx.coroutines.launch +import javax.inject.Inject class AboutActivity : BottomSheetActivity(), Injectable { + @Inject + lateinit var instanceInfoRepository: InstanceInfoRepository override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -32,6 +44,28 @@ class AboutActivity : BottomSheetActivity(), Injectable { binding.versionTextView.text = getString(R.string.about_app_version, getString(R.string.app_name), BuildConfig.VERSION_NAME) + binding.deviceInfo.text = getString( + R.string.about_device_info, + Build.MANUFACTURER, + Build.MODEL, + Build.VERSION.RELEASE, + Build.VERSION.SDK_INT + ) + + lifecycleScope.launch { + accountManager.activeAccount?.let { account -> + val instanceInfo = instanceInfoRepository.getInstanceInfo() + binding.accountInfo.text = getString( + R.string.about_account_info, + account.username, + account.domain, + instanceInfo.version + ) + binding.accountInfoTitle.show() + binding.accountInfo.show() + } + } + if (BuildConfig.CUSTOM_INSTANCE.isBlank()) { binding.aboutPoweredByTusky.hide() } @@ -47,6 +81,16 @@ class AboutActivity : BottomSheetActivity(), Injectable { binding.aboutLicensesButton.setOnClickListener { startActivityWithSlideInAnimation(Intent(this, LicenseActivity::class.java)) } + + binding.copyDeviceInfo.setOnClickListener { + val text = "${binding.versionTextView.text}\n\nDevice:\n\n${binding.deviceInfo.text}\n\nAccount:\n\n${binding.accountInfo.text}" + val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText("Tusky version information", text) + clipboard.setPrimaryClip(clip) + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) { + Toast.makeText(this, getString(R.string.about_copied), Toast.LENGTH_SHORT).show() + } + } } } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/instanceinfo/InstanceInfo.kt b/app/src/main/java/com/keylesspalace/tusky/components/instanceinfo/InstanceInfo.kt index bb97621c1..582df02e8 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/instanceinfo/InstanceInfo.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/instanceinfo/InstanceInfo.kt @@ -28,5 +28,6 @@ data class InstanceInfo( val maxMediaAttachments: Int, val maxFields: Int, val maxFieldNameLength: Int?, - val maxFieldValueLength: Int? + val maxFieldValueLength: Int?, + val version: String? ) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/instanceinfo/InstanceInfoRepository.kt b/app/src/main/java/com/keylesspalace/tusky/components/instanceinfo/InstanceInfoRepository.kt index bfc5a9b8c..1045fe480 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/instanceinfo/InstanceInfoRepository.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/instanceinfo/InstanceInfoRepository.kt @@ -99,7 +99,8 @@ class InstanceInfoRepository @Inject constructor( maxMediaAttachments = instanceInfo?.maxMediaAttachments ?: DEFAULT_MAX_MEDIA_ATTACHMENTS, maxFields = instanceInfo?.maxFields ?: DEFAULT_MAX_ACCOUNT_FIELDS, maxFieldNameLength = instanceInfo?.maxFieldNameLength, - maxFieldValueLength = instanceInfo?.maxFieldValueLength + maxFieldValueLength = instanceInfo?.maxFieldValueLength, + version = instanceInfo?.version ) } } diff --git a/app/src/main/res/drawable/ic_content_copy_24.xml b/app/src/main/res/drawable/ic_content_copy_24.xml new file mode 100644 index 000000000..bac0f6001 --- /dev/null +++ b/app/src/main/res/drawable/ic_content_copy_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 91919bc6b..0b46cda4c 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -21,104 +21,190 @@ android:layout_gravity="center" android:textDirection="anyRtl"> - + + + + + android:textAppearance="@style/TextAppearance.AppCompat.Medium" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/versionTextView" + tools:text="Your device" /> + + + + + + + + - + android:textAppearance="@style/TextAppearance.AppCompat.Subhead" + app:layout_constraintEnd_toEndOf="@+id/copyDeviceInfo" + app:layout_constraintStart_toStartOf="@+id/deviceInfo" + app:layout_constraintTop_toBottomOf="@+id/accountInfo" /> + app:layout_constraintEnd_toEndOf="@+id/aboutWebsiteInfoTextView" + app:layout_constraintStart_toStartOf="@+id/aboutWebsiteInfoTextView" + app:layout_constraintTop_toBottomOf="@id/aboutWebsiteInfoTextView" />