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
"Create poll" UI #1143
"Create poll" UI #1143
Conversation
e3c4371
to
222873f
Compare
📱 Scan the QR code below to install the build (arm64 only) for this PR. |
67b23fc
to
051ef60
Compare
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## develop #1143 +/- ##
===========================================
+ Coverage 56.87% 57.09% +0.22%
===========================================
Files 1039 1044 +5
Lines 26812 27092 +280
Branches 5544 5592 +48
===========================================
+ Hits 15248 15469 +221
- Misses 9168 9201 +33
- Partials 2396 2422 +26
☔ View full report in Codecov by Sentry. |
2c31714
to
319e9c2
Compare
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 work, a few remarks and one (or 2) blocking points.
Also maybe add the create poll flow in the Maestro test (can be done later of course).
EDIT: Creating a poll worked :)
@@ -83,6 +83,11 @@ class MessageComposerPresenter @Inject constructor( | |||
canShareLocation.value = featureFlagService.isFeatureEnabled(FeatureFlags.LocationSharing) | |||
} | |||
|
|||
val canCreatePoll = remember { mutableStateOf(false) } | |||
LaunchedEffect(Unit) { | |||
canCreatePoll.value = featureFlagService.isFeatureEnabled(FeatureFlags.Polls) |
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 update the string here:
https://github.com/vector-im/element-x-android/blob/41d0d21c808353f91a0d4ceedcb4321a94cf3f31/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt#L32
"Render poll events in the timeline"
since it also a flag to create poll. I propose "Create poll and render poll events in the timeline"
, but you choose.
private const val MIN_ANSWERS = 2; | ||
private const val MAX_ANSWERS = 20; | ||
private const val MAX_ANSWER_LENGTH = 240; | ||
private const val MAX_SELECTIONS = 1; |
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.
remove the ;
. You are doing too much Rust :)
}, | ||
restore = { | ||
mutableStateOf( | ||
when { |
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 is a problem here, you are not using it
:
when { | |
when(it) { |
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.
Oh damn, thanks, this is fatigue, I was wondering all day why intellij was underlying that when
and couldn't fathom.
return map { answer -> | ||
Answer( | ||
text = answer, | ||
canDelete = this.size > MIN_ANSWERS, |
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 confirm with product, but I fill weird not being able to delete an option if there is only 2 options. It's still possible to add an option, then delete the undesired one, so not a big deal though.
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 was explicitly specced by Product
pollKind = pollKind, | ||
) | ||
// analyticsService.capture(PollCreate()) // TODO: Send PollCreate analytics. | ||
navigateUp() |
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.
Is there a risk that calling this will cancel the poll creation (since the scope will be cancelled)?
Also we generally let the Node handle the navigation, so better to follow the existing pattern. The presenter set a boolean to the State that the flow is over, and the View communicate to the Node to handle the navigation.
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.
Is there a risk that calling this will cancel the poll creation (since the scope will be cancelled)?
Yes there is, though generally the rust sdk is very quick and I never saw it happen. In general I think this might be a bigger architectural problem as all our presenters use rememberCoroutineScope()
.
Also we generally let the Node handle the navigation, so better to follow the existing pattern. The presenter set a boolean to the State that the flow is over, and the View communicate to the Node to handle the navigation.
I've seen another case where a custom navigator has been used (MessagesNavigator
) so I thought this approach would be better, the added benefit is that it is testable.
// analyticsService.capture(PollCreate()) // TODO: Send PollCreate analytics. | ||
navigateUp() | ||
} else { | ||
Timber.e("Cannot create poll") |
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 guess this else block can be removed, the log is not adding lots of value. Or just change it to a debug log.
|
||
@OptIn(ExperimentalMaterial3Api::class) | ||
@Composable | ||
fun CreatePollView( |
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 cannot scroll the content when the keyboard is open, So I cannot see the entered text for the option 5 (depending on your phone size).
1418877
to
35416d8
Compare
Addressed all comments except for: #1143 (comment) |
event.text.substring(0, MAX_ANSWER_LENGTH) | ||
} else { | ||
event.text | ||
} |
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.
You can simplify with val text = event.text.take(MAX_ANSWER_LENGTH)
@Assisted buildContext: BuildContext, | ||
@Assisted plugins: List<Plugin>, | ||
presenterFactory: CreatePollPresenter.Factory, | ||
analyticsService: AnalyticsService, |
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 the CI to be happy, this line has to be commented out. We hunt all the warnings.
I've completely commented out the analytics code because the analytics PR is stuck. |
Kudos, SonarCloud Quality Gate passed! |
@@ -24,6 +24,7 @@ | |||
import androidx.compose.material.ListItem |
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.
⚠️ Using a material import while also using the material3 library
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! LGTM.
NB: This is missing analytics, which will be added once matrix-org/matrix-analytics-events#85 is merged.
Closes element-hq/element-meta#2011