Add option to send beta feedback

This commit is contained in:
Valere 2021-05-12 10:07:51 +02:00
parent 03f2b516a0
commit eb18b23528
14 changed files with 195 additions and 54 deletions

View File

@ -161,7 +161,7 @@ Formatter\.formatShortFileSize===1
# android\.text\.TextUtils # android\.text\.TextUtils
### This is not a rule, but a warning: the number of "enum class" has changed. For Json classes, it is mandatory that they have `@JsonClass(generateAdapter = false)`. If the enum is not used as a Json class, change the value in file forbidden_strings_in_code.txt ### This is not a rule, but a warning: the number of "enum class" has changed. For Json classes, it is mandatory that they have `@JsonClass(generateAdapter = false)`. If the enum is not used as a Json class, change the value in file forbidden_strings_in_code.txt
enum class===99 enum class===100
### Do not import temporary legacy classes ### Do not import temporary legacy classes
import org.matrix.android.sdk.internal.legacy.riot===3 import org.matrix.android.sdk.internal.legacy.riot===3

View File

@ -55,6 +55,7 @@ import im.vector.app.features.permalink.PermalinkHandler
import im.vector.app.features.popup.DefaultVectorAlert import im.vector.app.features.popup.DefaultVectorAlert
import im.vector.app.features.popup.PopupAlertManager import im.vector.app.features.popup.PopupAlertManager
import im.vector.app.features.popup.VerificationVectorAlert import im.vector.app.features.popup.VerificationVectorAlert
import im.vector.app.features.rageshake.ReportType
import im.vector.app.features.rageshake.VectorUncaughtExceptionHandler import im.vector.app.features.rageshake.VectorUncaughtExceptionHandler
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.settings.VectorSettingsActivity import im.vector.app.features.settings.VectorSettingsActivity
@ -216,6 +217,9 @@ class HomeActivity :
SpaceInviteBottomSheet.newInstance(sharedAction.spaceId) SpaceInviteBottomSheet.newInstance(sharedAction.spaceId)
.show(supportFragmentManager, "SPACE_INVITE") .show(supportFragmentManager, "SPACE_INVITE")
} }
HomeActivitySharedAction.SendSpaceFeedBack -> {
bugReporter.openBugReportScreen(this, ReportType.SPACE_BETA_FEEDBACK)
}
}.exhaustive }.exhaustive
} }
.disposeOnDestroy() .disposeOnDestroy()
@ -449,11 +453,11 @@ class HomeActivity :
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.menu_home_suggestion -> { R.id.menu_home_suggestion -> {
bugReporter.openBugReportScreen(this, true) bugReporter.openBugReportScreen(this, ReportType.SUGGESTION)
return true return true
} }
R.id.menu_home_report_bug -> { R.id.menu_home_report_bug -> {
bugReporter.openBugReportScreen(this, false) bugReporter.openBugReportScreen(this, ReportType.BUG_REPORT)
return true return true
} }
R.id.menu_home_init_sync_legacy -> { R.id.menu_home_init_sync_legacy -> {

View File

@ -29,4 +29,5 @@ sealed class HomeActivitySharedAction : VectorSharedAction {
data class OpenSpacePreview(val spaceId: String) : HomeActivitySharedAction() data class OpenSpacePreview(val spaceId: String) : HomeActivitySharedAction()
data class OpenSpaceInvite(val spaceId: String) : HomeActivitySharedAction() data class OpenSpaceInvite(val spaceId: String) : HomeActivitySharedAction()
data class ShowSpaceSettings(val spaceId: String) : HomeActivitySharedAction() data class ShowSpaceSettings(val spaceId: String) : HomeActivitySharedAction()
object SendSpaceFeedBack : HomeActivitySharedAction()
} }

View File

@ -16,6 +16,8 @@
package im.vector.app.features.rageshake package im.vector.app.features.rageshake
import android.content.Context
import android.content.Intent
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.Toast import android.widget.Toast
@ -27,10 +29,17 @@ import im.vector.app.R
import im.vector.app.core.di.ScreenComponent import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityBugReportBinding import im.vector.app.databinding.ActivityBugReportBinding
import org.matrix.android.sdk.api.extensions.tryOrNull
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
enum class ReportType {
BUG_REPORT,
SUGGESTION,
SPACE_BETA_FEEDBACK
}
/** /**
* Form to send a bug report * Form to send a bug report
*/ */
@ -46,7 +55,7 @@ class BugReportActivity : VectorBaseActivity<ActivityBugReportBinding>() {
private val viewModel: BugReportViewModel by viewModel() private val viewModel: BugReportViewModel by viewModel()
private var forSuggestion: Boolean = false private var reportType: ReportType = ReportType.BUG_REPORT
override fun initUiAndData() { override fun initUiAndData() {
configureToolbar(views.bugReportToolbar) configureToolbar(views.bugReportToolbar)
@ -60,15 +69,38 @@ class BugReportActivity : VectorBaseActivity<ActivityBugReportBinding>() {
views.bugReportButtonIncludeScreenshot.isEnabled = false views.bugReportButtonIncludeScreenshot.isEnabled = false
} }
forSuggestion = intent.getBooleanExtra("FOR_SUGGESTION", false) reportType = intent.getStringExtra(REPORT_TYPE_EXTRA)?.let {
tryOrNull { ReportType.valueOf(it) }
} ?: ReportType.BUG_REPORT
// Default screen is for bug report, so modify it for suggestion // Default screen is for bug report, so modify it for suggestion
if (forSuggestion) { when (reportType) {
ReportType.BUG_REPORT -> {
supportActionBar?.setTitle(R.string.title_activity_bug_report)
views.bugReportButtonContactMe.isVisible = false
}
ReportType.SUGGESTION -> {
supportActionBar?.setTitle(R.string.send_suggestion) supportActionBar?.setTitle(R.string.send_suggestion)
views.bugReportFirstText.setText(R.string.send_suggestion_content) views.bugReportFirstText.setText(R.string.send_suggestion_content)
views.bugReportTextInputLayout.hint = getString(R.string.send_suggestion_report_placeholder) views.bugReportTextInputLayout.hint = getString(R.string.send_suggestion_report_placeholder)
views.bugReportButtonContactMe.isVisible = true
hideBugReportOptions()
}
ReportType.SPACE_BETA_FEEDBACK -> {
supportActionBar?.setTitle(R.string.send_feedback_space_title)
views.bugReportFirstText.setText(R.string.send_feedback_space_info)
views.bugReportTextInputLayout.hint = getString(R.string.feedback)
views.bugReportButtonContactMe.isVisible = true
hideBugReportOptions()
}
}
}
private fun hideBugReportOptions() {
views.bugReportLogsDescription.isVisible = false views.bugReportLogsDescription.isVisible = false
views.bugReportButtonIncludeLogs.isChecked = false views.bugReportButtonIncludeLogs.isChecked = false
@ -79,11 +111,6 @@ class BugReportActivity : VectorBaseActivity<ActivityBugReportBinding>() {
views.bugReportButtonIncludeKeyShareHistory.isChecked = false views.bugReportButtonIncludeKeyShareHistory.isChecked = false
views.bugReportButtonIncludeKeyShareHistory.isVisible = false views.bugReportButtonIncludeKeyShareHistory.isVisible = false
// Keep the screenshot
} else {
supportActionBar?.setTitle(R.string.title_activity_bug_report)
}
} }
private fun setupViews() { private fun setupViews() {
@ -134,24 +161,32 @@ class BugReportActivity : VectorBaseActivity<ActivityBugReportBinding>() {
views.bugReportProgressView.progress = 0 views.bugReportProgressView.progress = 0
bugReporter.sendBugReport(this, bugReporter.sendBugReport(this,
forSuggestion, reportType,
views.bugReportButtonIncludeLogs.isChecked, views.bugReportButtonIncludeLogs.isChecked,
views.bugReportButtonIncludeCrashLogs.isChecked, views.bugReportButtonIncludeCrashLogs.isChecked,
views.bugReportButtonIncludeKeyShareHistory.isChecked, views.bugReportButtonIncludeKeyShareHistory.isChecked,
views.bugReportButtonIncludeScreenshot.isChecked, views.bugReportButtonIncludeScreenshot.isChecked,
views.bugReportEditText.text.toString(), views.bugReportEditText.text.toString(),
state.serverVersion, state.serverVersion,
views.bugReportButtonContactMe.isChecked,
object : BugReporter.IMXBugReportListener { object : BugReporter.IMXBugReportListener {
override fun onUploadFailed(reason: String?) { override fun onUploadFailed(reason: String?) {
try { try {
if (!reason.isNullOrEmpty()) { if (!reason.isNullOrEmpty()) {
if (forSuggestion) { when (reportType) {
Toast.makeText(this@BugReportActivity, ReportType.BUG_REPORT -> {
getString(R.string.send_suggestion_failed, reason), Toast.LENGTH_LONG).show()
} else {
Toast.makeText(this@BugReportActivity, Toast.makeText(this@BugReportActivity,
getString(R.string.send_bug_report_failed, reason), Toast.LENGTH_LONG).show() getString(R.string.send_bug_report_failed, reason), Toast.LENGTH_LONG).show()
} }
ReportType.SUGGESTION -> {
Toast.makeText(this@BugReportActivity,
getString(R.string.send_suggestion_failed, reason), Toast.LENGTH_LONG).show()
}
ReportType.SPACE_BETA_FEEDBACK -> {
Toast.makeText(this@BugReportActivity,
getString(R.string.space_feedback_failed, reason), Toast.LENGTH_LONG).show()
}
}
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## onUploadFailed() : failed to display the toast") Timber.e(e, "## onUploadFailed() : failed to display the toast")
@ -178,11 +213,17 @@ class BugReportActivity : VectorBaseActivity<ActivityBugReportBinding>() {
override fun onUploadSucceed() { override fun onUploadSucceed() {
try { try {
if (forSuggestion) { when (reportType) {
Toast.makeText(this@BugReportActivity, R.string.send_suggestion_sent, Toast.LENGTH_LONG).show() ReportType.BUG_REPORT -> {
} else {
Toast.makeText(this@BugReportActivity, R.string.send_bug_report_sent, Toast.LENGTH_LONG).show() Toast.makeText(this@BugReportActivity, R.string.send_bug_report_sent, Toast.LENGTH_LONG).show()
} }
ReportType.SUGGESTION -> {
Toast.makeText(this@BugReportActivity, R.string.send_suggestion_sent, Toast.LENGTH_LONG).show()
}
ReportType.SPACE_BETA_FEEDBACK -> {
Toast.makeText(this@BugReportActivity, R.string.space_feedback_sent, Toast.LENGTH_LONG).show()
}
}
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## onUploadSucceed() : failed to dismiss the toast") Timber.e(e, "## onUploadSucceed() : failed to dismiss the toast")
} }
@ -214,4 +255,14 @@ class BugReportActivity : VectorBaseActivity<ActivityBugReportBinding>() {
super.onBackPressed() super.onBackPressed()
} }
companion object {
private const val REPORT_TYPE_EXTRA = "REPORT_TYPE_EXTRA"
fun intent(context: Context, reportType: ReportType): Intent {
return Intent(context, BugReportActivity::class.java).apply {
putExtra(REPORT_TYPE_EXTRA, reportType.name)
}
}
}
} }

View File

@ -149,7 +149,7 @@ class BugReporter @Inject constructor(
* Send a bug report. * Send a bug report.
* *
* @param context the application context * @param context the application context
* @param forSuggestion true to send a suggestion * @param reportType The report type (bug, suggestion, feedback)
* @param withDevicesLogs true to include the device log * @param withDevicesLogs true to include the device log
* @param withCrashLogs true to include the crash logs * @param withCrashLogs true to include the crash logs
* @param withKeyRequestHistory true to include the crash logs * @param withKeyRequestHistory true to include the crash logs
@ -159,13 +159,14 @@ class BugReporter @Inject constructor(
*/ */
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
fun sendBugReport(context: Context, fun sendBugReport(context: Context,
forSuggestion: Boolean, reportType: ReportType,
withDevicesLogs: Boolean, withDevicesLogs: Boolean,
withCrashLogs: Boolean, withCrashLogs: Boolean,
withKeyRequestHistory: Boolean, withKeyRequestHistory: Boolean,
withScreenshot: Boolean, withScreenshot: Boolean,
theBugDescription: String, theBugDescription: String,
serverVersion: String, serverVersion: String,
canContact: Boolean = false,
listener: IMXBugReportListener?) { listener: IMXBugReportListener?) {
// enumerate files to delete // enumerate files to delete
val mBugReportFiles: MutableList<File> = ArrayList() val mBugReportFiles: MutableList<File> = ArrayList()
@ -246,13 +247,11 @@ class BugReporter @Inject constructor(
} }
if (!mIsCancelled) { if (!mIsCancelled) {
val text = "[Element] " + val text = when (reportType) {
if (forSuggestion) { ReportType.BUG_REPORT -> "[Element] $bugDescription"
"[Suggestion] " ReportType.SUGGESTION -> "[Element] [Suggestion] $bugDescription"
} else { ReportType.SPACE_BETA_FEEDBACK -> "[Element] [spaces-feedback] $bugDescription"
"" }
} +
bugDescription
// build the multi part request // build the multi part request
val builder = BugReporterMultipartBody.Builder() val builder = BugReporterMultipartBody.Builder()
@ -260,6 +259,7 @@ class BugReporter @Inject constructor(
.addFormDataPart("app", "riot-android") .addFormDataPart("app", "riot-android")
.addFormDataPart("user_agent", Matrix.getInstance(context).getUserAgent()) .addFormDataPart("user_agent", Matrix.getInstance(context).getUserAgent())
.addFormDataPart("user_id", userId) .addFormDataPart("user_id", userId)
.addFormDataPart("can_contact", canContact.toString())
.addFormDataPart("device_id", deviceId) .addFormDataPart("device_id", deviceId)
.addFormDataPart("version", versionProvider.getVersion(longFormat = true, useBuildNumber = false)) .addFormDataPart("version", versionProvider.getVersion(longFormat = true, useBuildNumber = false))
.addFormDataPart("branch_name", context.getString(R.string.git_branch_name)) .addFormDataPart("branch_name", context.getString(R.string.git_branch_name))
@ -321,9 +321,12 @@ class BugReporter @Inject constructor(
// Special for RiotX // Special for RiotX
builder.addFormDataPart("label", "[Element]") builder.addFormDataPart("label", "[Element]")
// Suggestion when (reportType) {
if (forSuggestion) { ReportType.BUG_REPORT -> {
builder.addFormDataPart("label", "[Suggestion]") /* nop */
}
ReportType.SUGGESTION -> builder.addFormDataPart("label", "[Suggestion]")
ReportType.SPACE_BETA_FEEDBACK -> builder.addFormDataPart("label", "spaces-feedback")
} }
if (getCrashFile(context).exists()) { if (getCrashFile(context).exists()) {
@ -447,16 +450,14 @@ class BugReporter @Inject constructor(
/** /**
* Send a bug report either with email or with Vector. * Send a bug report either with email or with Vector.
*/ */
fun openBugReportScreen(activity: FragmentActivity, forSuggestion: Boolean = false) { fun openBugReportScreen(activity: FragmentActivity, reportType: ReportType = ReportType.BUG_REPORT) {
screenshot = takeScreenshot(activity) screenshot = takeScreenshot(activity)
activeSessionHolder.getSafeActiveSession()?.let { activeSessionHolder.getSafeActiveSession()?.let {
it.logDbUsageInfo() it.logDbUsageInfo()
it.cryptoService().logDbUsageInfo() it.cryptoService().logDbUsageInfo()
} }
val intent = Intent(activity, BugReportActivity::class.java) activity.startActivity(BugReportActivity.intent(activity, reportType))
intent.putExtra("FOR_SUGGESTION", forSuggestion)
activity.startActivity(intent)
} }
// ============================================================================================================== // ==============================================================================================================

View File

@ -16,13 +16,28 @@
package im.vector.app.features.spaces package im.vector.app.features.spaces
import android.view.View
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.utils.DebouncedClickListener
@EpoxyModelClass(layout = R.layout.item_space_beta_header) @EpoxyModelClass(layout = R.layout.item_space_beta_header)
abstract class SpaceBetaHeaderItem : VectorEpoxyModel<SpaceBetaHeaderItem.Holder>() { abstract class SpaceBetaHeaderItem : VectorEpoxyModel<SpaceBetaHeaderItem.Holder>() {
class Holder : VectorEpoxyHolder() @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var clickAction: View.OnClickListener? = null
override fun bind(holder: Holder) {
super.bind(holder)
holder.feedBackAction.setOnClickListener(DebouncedClickListener({
clickAction?.onClick(it)
}))
}
class Holder : VectorEpoxyHolder() {
val feedBackAction by bind<View>(R.id.spaceBetaFeedbackAction)
}
} }

View File

@ -101,4 +101,8 @@ class SpaceListFragment @Inject constructor(
override fun onGroupSelected(groupSummary: GroupSummary?) { override fun onGroupSelected(groupSummary: GroupSummary?) {
viewModel.handle(SpaceListAction.SelectLegacyGroup(groupSummary)) viewModel.handle(SpaceListAction.SelectLegacyGroup(groupSummary))
} }
override fun sendFeedBack() {
sharedActionViewModel.post(HomeActivitySharedAction.SendSpaceFeedBack)
}
} }

View File

@ -33,6 +33,8 @@ import im.vector.app.databinding.BottomSheetSpaceSettingsBinding
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.navigation.Navigator import im.vector.app.features.navigation.Navigator
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
import im.vector.app.features.rageshake.BugReporter
import im.vector.app.features.rageshake.ReportType
import im.vector.app.features.roomprofile.RoomProfileActivity import im.vector.app.features.roomprofile.RoomProfileActivity
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.spaces.manage.ManageType import im.vector.app.features.spaces.manage.ManageType
@ -58,6 +60,7 @@ class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment<BottomS
@Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var activeSessionHolder: ActiveSessionHolder
@Inject lateinit var avatarRenderer: AvatarRenderer @Inject lateinit var avatarRenderer: AvatarRenderer
@Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var vectorPreferences: VectorPreferences
@Inject lateinit var bugReporter: BugReporter
private val spaceArgs: SpaceBottomSheetSettingsArgs by args() private val spaceArgs: SpaceBottomSheetSettingsArgs by args()
@ -106,6 +109,10 @@ class SpaceSettingsMenuBottomSheet : VectorBaseBottomSheetDialogFragment<BottomS
views.addRooms.isVisible = canAddChild views.addRooms.isVisible = canAddChild
}.disposeOnDestroyView() }.disposeOnDestroyView()
views.spaceBetaTag.setOnClickListener {
bugReporter.openBugReportScreen(requireActivity(), ReportType.SPACE_BETA_FEEDBACK)
}
views.invitePeople.views.bottomSheetActionClickableZone.debouncedClicks { views.invitePeople.views.bottomSheetActionClickableZone.debouncedClicks {
dismiss() dismiss()
interactionListener?.onShareSpaceSelected(spaceArgs.spaceId) interactionListener?.onShareSpaceSelected(spaceArgs.spaceId)

View File

@ -16,6 +16,7 @@
package im.vector.app.features.spaces package im.vector.app.features.spaces
import android.view.View
import com.airbnb.epoxy.EpoxyController import com.airbnb.epoxy.EpoxyController
import im.vector.app.R import im.vector.app.R
import im.vector.app.RoomGroupingMethod import im.vector.app.RoomGroupingMethod
@ -109,7 +110,12 @@ class SpaceSummaryController @Inject constructor(
text(stringProvider.getString(R.string.spaces_header)) text(stringProvider.getString(R.string.spaces_header))
} }
spaceBetaHeaderItem { id("beta_header") } spaceBetaHeaderItem {
id("beta_header")
clickAction(View.OnClickListener {
callback?.sendFeedBack()
})
}
// show invites on top // show invites on top
@ -221,7 +227,7 @@ class SpaceSummaryController @Inject constructor(
fun onSpaceSettings(spaceSummary: RoomSummary) fun onSpaceSettings(spaceSummary: RoomSummary)
fun onToggleExpand(spaceSummary: RoomSummary) fun onToggleExpand(spaceSummary: RoomSummary)
fun onAddSpaceSelected() fun onAddSpaceSelected()
fun onGroupSelected(groupSummary: GroupSummary?) fun onGroupSelected(groupSummary: GroupSummary?)
fun sendFeedBack()
} }
} }

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M6.2887,10.748C8.7036,10.748 10.6612,8.7897 10.6612,6.374C10.6612,3.9583 8.7036,2 6.2887,2C3.8739,2 1.9163,3.9583 1.9163,6.374C1.9163,7.038 2.0642,7.6674 2.3288,8.2311L1.6,9.7683C1.2011,10.6099 2.0682,11.492 2.9165,11.1074L4.5258,10.378C5.0651,10.6159 5.6615,10.748 6.2887,10.748Z"
android:fillColor="#238CF5"
android:fillType="evenOdd"/>
<path
android:pathData="M12.6608,7.3739C12.6608,9.7896 10.7032,11.7479 8.2883,11.7479C7.8421,11.7479 7.4114,11.681 7.0059,11.5568C7.7732,12.2953 8.8076,12.7479 9.9456,12.7479C10.5605,12.7479 11.1451,12.6158 11.6737,12.3778L13.211,13.0887C14.0564,13.4796 14.9301,12.6043 14.5376,11.7597L13.8272,10.2308C14.0865,9.6672 14.2315,9.0378 14.2315,8.3739C14.2315,6.4535 13.0188,4.8221 11.3323,4.2339C12.1516,5.0289 12.6608,6.1419 12.6608,7.3739Z"
android:fillColor="#238CF5"
android:fillType="evenOdd"/>
</vector>

View File

@ -133,6 +133,15 @@
android:checked="false" android:checked="false"
android:text="@string/send_bug_report_include_key_share_history" /> android:text="@string/send_bug_report_include_key_share_history" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/bug_report_button_contact_me"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:checked="false"
android:text="@string/you_may_contact_me" />
<com.google.android.material.switchmaterial.SwitchMaterial <com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/bug_report_button_include_screenshot" android:id="@+id/bug_report_button_include_screenshot"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -30,7 +30,6 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/layout_horizontal_margin" android:layout_marginStart="@dimen/layout_horizontal_margin"
android:layout_marginEnd="8dp"
android:duplicateParentState="true" android:duplicateParentState="true"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
@ -39,12 +38,21 @@
android:textStyle="bold" android:textStyle="bold"
app:layout_constrainedWidth="true" app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@+id/spaceDescription" app:layout_constraintBottom_toTopOf="@+id/spaceDescription"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="@id/spaceBetaTag"
app:layout_constraintStart_toEndOf="@id/spaceAvatarImageView" app:layout_constraintStart_toEndOf="@id/spaceAvatarImageView"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" app:layout_constraintVertical_chainStyle="packed"
tools:text="@sample/matrix.json/data/displayName" /> tools:text="@sample/matrix.json/data/displayName" />
<ImageView
android:id="@+id/spaceBetaTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:src="@drawable/ic_beta_pill"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/spaceDescription" android:id="@+id/spaceDescription"
android:layout_width="0dp" android:layout_width="0dp"

View File

@ -39,6 +39,19 @@
android:text="@string/spaces_beta_welcome_to_spaces_desc" android:text="@string/spaces_beta_welcome_to_spaces_desc"
android:textColor="?riotx_text_secondary" android:textColor="?riotx_text_secondary"
android:textSize="15sp" /> android:textSize="15sp" />
<TextView
android:id="@+id/spaceBetaFeedbackAction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:layout_marginBottom="4dp"
android:text="@string/give_feedback"
android:drawableStart="@drawable/ic_feedback"
android:drawablePadding="8dp"
android:textColor="@color/vector_info_color"
android:textSize="15sp" />
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>

View File

@ -2167,6 +2167,14 @@
<string name="send_suggestion_sent">Thanks, the suggestion has been successfully sent</string> <string name="send_suggestion_sent">Thanks, the suggestion has been successfully sent</string>
<string name="send_suggestion_failed">The suggestion failed to be sent (%s)</string> <string name="send_suggestion_failed">The suggestion failed to be sent (%s)</string>
<string name="send_feedback_space_title">Spaces feedback</string>
<string name="feedback">Feedback</string>
<string name="send_feedback_space_info">Youre using a beta version of spaces. Your feedback will help inform the next versions. Your platform and username will be noted to help us use your feedback as much as we can. To leave the beta, visit your settings.</string>
<string name="you_may_contact_me">You may contact me if you have any follow up questions</string>
<string name="space_feedback_sent">Thanks, your feedback has been successfully sent</string>
<string name="space_feedback_failed">The feedback failed to be sent (%s)</string>
<string name="give_feedback">Give Feedback</string>
<string name="settings_labs_show_hidden_events_in_timeline">Show hidden events in timeline</string> <string name="settings_labs_show_hidden_events_in_timeline">Show hidden events in timeline</string>
<string name="settings_labs_show_complete_history_in_encrypted_room">"Show complete history in encrypted rooms"</string> <string name="settings_labs_show_complete_history_in_encrypted_room">"Show complete history in encrypted rooms"</string>