Skip to content
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

Merged
merged 15 commits into from
Apr 5, 2022

Conversation

ariskotsomitopoulos
Copy link
Contributor

@ariskotsomitopoulos ariskotsomitopoulos commented Apr 4, 2022

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)”).

Screenshot_20220404-195113_Element dbg Screenshot_20220405-133840_Element dbg

@ariskotsomitopoulos ariskotsomitopoulos requested review from a team and mnaturel and removed request for a team April 4, 2022 16:57
@github-actions
Copy link

github-actions bot commented Apr 4, 2022

Unit Test Results

110 files  ±0  110 suites  ±0   1m 18s ⏱️ +9s
195 tests ±0  195 ✔️ ±0  0 💤 ±0  0 ±0 
650 runs  ±0  650 ✔️ ±0  0 💤 ±0  0 ±0 

Results for commit 598892d. ± Comparison against base commit 3b8ffcf.

♻️ This comment has been updated with latest results.

@ouchadam ouchadam added the Z-NextRelease For issues and PRs which should be included in the NextRelease. label Apr 5, 2022
@@ -2374,6 +2385,29 @@ class TimelineFragment @Inject constructor(
}
}

/**
Copy link
Contributor

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

Copy link
Contributor Author

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
Copy link
Contributor

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 🙏

Copy link
Contributor Author

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"
Copy link
Contributor

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

Copy link
Contributor Author

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>"
Copy link
Contributor

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

Copy link
Contributor

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)

Copy link
Contributor Author

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.

  1. Yes I agree learn more can be also a string resource, will update it accordingly
  2. 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?

Copy link
Member

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.

Copy link
Contributor

@ouchadam ouchadam Apr 5, 2022

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!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bmarty I also observed it will do a clean up there.

@ouchadam I would suggest to create a separate string resource file for non translatable strings. And when we have dynamic URLs with multiple domains for sure we can add them in our translatable strings

Copy link
Member

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.setCancelable(true)
.setNegativeButton(R.string.action_not_now) { _, _ -> }
.setPositiveButton(R.string.action_try_it_out) { _, _ ->
timelineViewModel.onCleared() // We should first clear our viewModel
Copy link
Contributor

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~

Copy link
Contributor Author

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

Copy link
Contributor Author

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

Copy link
Contributor

@ouchadam ouchadam Apr 5, 2022

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

Copy link
Contributor Author

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

Copy link
Member

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.

Copy link
Contributor

@ouchadam ouchadam left a 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
Copy link
Member

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() =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like using = when the fun should not return anything. Can you use { instead?

Here it will return a TextView? which is highly unexpected.

image

Copy link
Contributor Author

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
Copy link
Member

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
Copy link
Member

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.

Copy link
Contributor Author

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"
Copy link
Member

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

Copy link
Contributor Author

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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please rearrange attributes

Copy link
Contributor Author

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

Copy link
Member

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>
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do yeap

Copy link
Member

@bmarty bmarty left a 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>
Copy link
Member

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.

Copy link
Contributor Author

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

Copy link
Member

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 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

vector/src/main/res/values/strings_login_v2.xml Outdated Show resolved Hide resolved
Copy link
Member

@bmarty bmarty left a 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>
Copy link
Member

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

Copy link
Contributor Author

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

@ariskotsomitopoulos
Copy link
Contributor Author

Update: We achieved to avoid manually calling viewModel onCleared, with an alternative approach. Thanks @ouchadam for that!

@@ -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)-->
Copy link
Member

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 :/

Copy link
Contributor Author

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?

Copy link
Member

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
Copy link
Member

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

Copy link
Contributor Author

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

Copy link
Member

@bmarty bmarty left a 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.

@bmarty bmarty merged commit 0f14652 into develop Apr 5, 2022
@bmarty bmarty deleted the feature/aris/threads_beta_infrom_users_on_reply branch April 5, 2022 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Z-NextRelease For issues and PRs which should be included in the NextRelease.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants