-
Notifications
You must be signed in to change notification settings - Fork 781
Threads Beta opt-in mechanism #5692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Threads Beta opt-in mechanism #5692
Conversation
@@ -2374,6 +2385,29 @@ class TimelineFragment @Inject constructor( | |||
} | |||
} | |||
|
|||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could avoid this comment by including the context in the function name displayThreadsBetaOptInDialog
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The truth is thats a better name !
@@ -82,4 +82,27 @@ | |||
tools:ignore="MissingPrefix" | |||
tools:visibility="visible" /> | |||
|
|||
|
|||
<TextView |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be great to get a screenshot of this view 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will add to PR's description!
android:visibility="gone" | ||
tools:visibility="visible" | ||
android:text="@string/beta_title_bottom_sheet_action" | ||
android:textColor="@color/palette_white" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to double check, should this use the theme colours? I'm guessing we're not using them because the background colour is hardcoded blue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeap, we are not using them, its the same for both themes!
* Generates and return an Html spanned string to be rendered especially in dialogs | ||
*/ | ||
fun getBetaEnableThreadsMessage(): Spanned { | ||
val href = "<a href='$learnMoreUrl'>Learn more</a>.<br><br>" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we want to allow translations here we'll need to move this Learn more
to the resources
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thinking a little more, assuming the learnMoreUrl
doesn't need to be dynamic, it could be in the string resource (we've done something similar for the EMS copy in the onboarding)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The easiest way to implement that functionality was to include <a href='$learnMoreUrl'>Learn more</a>.<br><br>
in a string resources but I didn't want to do that. Thats why I decoupled the html part with the rest.
- Yes I agree
learn more
can be also a string resource, will update it accordingly - I have not seen any
http
links in any of our string resources so I tried to avoid it. And if we do that we should mark it as not translatable to avoid trying to translate them. Where exactly we do that in the onboarding?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have several instance of "learn more" in the string, maybe create a generic one, and we can do some cleanup during the next welbate sync.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for 2.
, I've just realised it hasn't been pushed yet whilst we figure out the exact url 🤦 the benefit of including the url in the translatable strings is that we could also change the domain based on locale eg DE could use the .de domain myurl.de
although this only works if the url is static 🤔
not a blocker for the PR ^^^ there's no convention for having urls in code vs resources at the moment (from what I can tell at least!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to translate the URL, this is fine, but please let the formatting out of the string resource.
Also I think the URL can be translated, but out of Weblate, since this is quite technical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
example of url in the resources: https://github.com./vector-im/element-android/blob/main/vector-config/src/main/res/values/config.xml#L7
.setCancelable(true) | ||
.setNegativeButton(R.string.action_not_now) { _, _ -> } | ||
.setPositiveButton(R.string.action_try_it_out) { _, _ -> | ||
timelineViewModel.onCleared() // We should first clear our viewModel |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to clear the viewmodel if we're restarting the app? I'm wondering if we'll get it for free~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't there is a crash in the live events observers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only happening if we RR the app from the Timeline, while the observers are active
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah that is strange, I expected restarting the app to also call timelineViewModel.onCleared()
, perhaps there's a existing issue in the screen with the way the listeners are being set/released (if they're tied to the viewmodel lifecycle rather than the fragment)
not a blocker for this PR, just something to bear in mind for the future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, definitely its something wrong here, manually clearing the viewModel it's a workaround
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this is quite strange to call onCleared
manually (there is no other case like this in the codebase). There is probably another bug for your unexpected behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tiny comment about the Learn more copy, otherwise LGTM! 💯
@@ -106,12 +109,14 @@ abstract class BottomSheetActionItem : VectorEpoxyModel<BottomSheetActionItem.Ho | |||
} else { | |||
holder.text.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null) | |||
} | |||
holder.betaLabel.isVisible = showBetaLabel |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra space! (ktlint should complain about it now)
* Display a dialog that will let the user to enable threads | ||
*/ | ||
|
||
private fun displayThreadsBetaNotice() = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, and I prefer that than return Unit manually
.setCancelable(true) | ||
.setNegativeButton(R.string.action_not_now) { _, _ -> } | ||
.setPositiveButton(R.string.action_try_it_out) { _, _ -> | ||
timelineViewModel.onCleared() // We should first clear our viewModel |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this is quite strange to call onCleared
manually (there is no other case like this in the codebase). There is probably another bug for your unexpected behavior.
@@ -450,7 +450,8 @@ class MessageActionsViewModel @AssistedInject constructor( | |||
private fun canReplyInThread(event: TimelineEvent, | |||
messageContent: MessageContent?, | |||
actionPermissions: ActionPermissions): Boolean { | |||
if (!vectorPreferences.areThreadMessagesEnabled()) return false | |||
/* We let reply in thread visible even if threads are not enabled, with an enhanced flow to attract users */ | |||
// if (!vectorPreferences.areThreadMessagesEnabled()) return false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to add some indentation here and for the comment above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
) { | ||
|
||
companion object { | ||
const val learnMoreUrl = "https://element.io/help#threads" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably something to move to the vector-config
module, maybe in a new urls.xml
resource file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thats what we discussed with adam
android:layout_marginEnd="1dp" | ||
android:paddingBottom="3dp" | ||
android:visibility="gone" | ||
tools:visibility="visible" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please rearrange attributes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, also maybe we can force ktlintformat
to do that if possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ktlint only works on Kotlin files AFAIK, not XML resources.
But if you found a solution for this, it could be very nice.
@@ -734,6 +735,8 @@ | |||
<string name="search_thread_from_a_thread">From a Thread</string> | |||
<string name="threads_notice_migration_title">Threads Approaching Beta 🎉</string> | |||
<string name="threads_notice_migration_message">We’re getting closer to releasing a public Beta for Threads.\n\nAs we prepare for it, we need to make some changes: threads created before this point will be displayed as regular replies.\n\nThis will be a one-off transition as Threads are now part of the Matrix specification.</string> | |||
<string name="threads_beta_enable_notice_title">Threads Beta</string> | |||
<string name="threads_beta_enable_notice_message">Threads help keep your conversations on-topic and easy to track. %sEnabling threads will refresh the app. This may take longer for some accounts.</string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a comment above to explain with what %s
will be replaced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do yeap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
timelineViewModel.onCleared()
is still annoying me :/
<resources> | ||
<!-- This file contains url values--> | ||
|
||
<string name="threads_learn_more_url" translatable="false">https://element.io/help#threads</string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This anchor threads
does not exist (yet), and today this page does not mention thread the user experience will be quite bad. But @ariskotsomitopoulos told me that the webpage will be ready today or tomorrow.
So OK to merge the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeap, it should be deployed before the release as we discussed. All platforms will release that url
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to be live now 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should find another way to avoid calling onCleared()
@@ -2137,7 +2142,6 @@ | |||
<string name="direct_room_profile_encrypted_subtitle">Messages here are end-to-end encrypted.\n\nYour messages are secured with locks and only you and the recipient have the unique keys to unlock them.</string> | |||
<string name="room_profile_section_security">Security</string> | |||
<string name="room_profile_section_restore_security">Restore Encryption</string> | |||
<string name="room_profile_section_security_learn_more">Learn more</string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the proper way to remove string. Please refer to this: https://github.com./vector-im/element-android/blob/main/CONTRIBUTING.md#removing-existing-strings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will revert that and do that on a separate commit
Update: We achieved to avoid manually calling viewModel |
@@ -43,7 +43,7 @@ | |||
<string name="login_set_msisdn_title_2">Associate a phone number</string> | |||
<string name="login_set_msisdn_notice_2">Associate a phone number to optionally allow people you know to discover you.</string> | |||
<string name="login_set_msisdn_mandatory_notice_2">The server %s requires you to associate a phone number to create an account.</string> | |||
<!-- %s will be replaced by the value of action_learn_more ("Learn more" in English)--> | |||
<!-- %S will be replaced by the value of login_server_modular_learn_more ("Learn more" in English)--> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you have been a bit fast with the "replace all" command :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I never use that command, now its reverted as is in develop, in develop is with capital %S, what do you mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
class ThreadsManager @Inject constructor( | ||
private val vectorPreferences: VectorPreferences, | ||
private val lightweightSettingsStorage: LightweightSettingsStorage, | ||
private val context: Context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be a stringProvider
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice point, will update asap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update! Happy to merge it now.
Threads Beta Opt-In
If threads are disabled in Labs:
Hide the thread button in the room header. Keep the “Reply in thread” action in the bottom sheet, which shows a BETA badge until the stable version is released. On tapping on the “Reply in thread” action a modal is shown to enable threads in Labs. Ideally, this would be a one-step action (refer to “Beta opt-in — Modal (direct)”).