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

Integrate WYSIWYG editor #7288

Merged
merged 11 commits into from
Oct 11, 2022
Merged

Integrate WYSIWYG editor #7288

merged 11 commits into from
Oct 11, 2022

Conversation

jmartinesp
Copy link
Member

@jmartinesp jmartinesp commented Oct 4, 2022

Type of change

  • Feature
  • Bugfix
  • Technical
  • Other :

Content

Adds the io.element.android:wysiwyg library, which features the new WYSIWYG editor. Modified MessageComposerFragment to be able to toggle between the current composer and the new one using a labs flag.

Motivation and context

We want to integrate the initial version of the WYSIWIG editor into the real app to be able to send rich text messages without having to use markdown.

Screenshots / GIFs

Before After
Screenshot_1664984239 Screenshot_1664984145

Tests

  • Go to Settings > Labs, toggle 'Enable rich text editor'.
  • Open any room or DM.
  • Type any text using formatting and send it.
  • You can also test if formatted text is sent for message edits, quotes, replies, etc.

Tested devices

  • Physical
  • Emulator
  • OS version(s): 11, 12

Checklist

@jmartinesp jmartinesp self-assigned this Oct 4, 2022
@jmartinesp jmartinesp force-pushed the tech/integrate-wysiwyg branch 3 times, most recently from 754f7f3 to 0cbc8cb Compare October 5, 2022 15:46
@jmartinesp jmartinesp marked this pull request as ready for review October 5, 2022 15:47
@jmartinesp jmartinesp requested review from a team and yostyle and removed request for a team October 5, 2022 15:48
@jmartinesp
Copy link
Member Author

Please note that this is the just the initial version of the editor, so it lacks some features like autocomplete, lists, links, pills, etc. and might have some corner cases that we might have missed on our testing sessions, that's expected.

@bmarty bmarty requested review from bmarty and removed request for yostyle October 7, 2022 09:36
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.

Nice work!
Quick smoke test with the RTE enabled, seems to work fine.
The design will be updated? Could be nice to have something similar Element Web with popup:

image

@@ -0,0 +1 @@
Add WYSIWYG editor.
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a 7288.sdk file to describe the changes in the SDK API? Thanks.

lastMessageContent.formattedBody
} else {
lastMessageContent?.body
} ?: return ""
Copy link
Member

Choose a reason for hiding this comment

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

Nit: maybe create an extension

fun MessageContent?.getFormattedBody(): String? {
    return if (this is MessageContentWithFormattedBody) {
        formattedBody
    } else {
        this?.body
    }
}

newBodyAutoMarkdown: Boolean,
msgType: String,
compatibilityText: String
): Event {
val content = if (newBodyFormattedText != null) {
TextContent(newBodyText.toString(), newBodyFormattedText.toString()).toMessageTextContent(msgType)
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should consider changing TextContent to have 2 CharSequence members.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it probably makes sense to keep using String for these, as both text and formattedText are expected to be the plain text representation of the contents (either a plain text string or the HTML format of that same text). I'm no expert on this part of the code though, so if you think we should change it I can do it.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, you are right. Thanks

@@ -66,7 +67,7 @@ fun EditText.setTextIfDifferent(newText: CharSequence?): Boolean {
// Previous text is the same. No op
return false
}
setText(newText)
setText(newText, TextView.BufferType.SPANNABLE)
Copy link
Member

Choose a reason for hiding this comment

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

Since the extension is used at other places, maybe add a parameter with default value to use TextView.BufferType.SPANNABLE on demand only?

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, this change wasn't needed, I forgot to revert a test. Great catch!

if (message.isNotEmpty()) {
ParsedCommand.ChangeDisplayNameForRoom(displayName = message)
if (trimmedMessage.isNotEmpty()) {
ParsedCommand.ChangeDisplayNameForRoom(displayName = trimmedMessage)
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 better to reuse message name instead of trimmedMessage to avoid too many changes in this file.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done, but I had to add a suppression for name shadowing.

autoMarkdown = false
)
} else {
room.sendService().sendFormattedTextMessage(parsedCommand.message.toString(), parsedCommand.formattedMessage)
Copy link
Member

Choose a reason for hiding this comment

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

For parity with the if block, maybe use named param, and 1 per line.

import im.vector.app.databinding.ViewRichTextMenuButtonBinding
import io.element.android.wysiwyg.InlineFormat

class RichTextComposerView @JvmOverloads constructor(
Copy link
Member

Choose a reason for hiding this comment

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

Maybe rename to RichTextComposerLayout (see my other remark about renaming)?

defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), MessageComposer {

val views: ComposerRichTextLayoutBinding
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 private I think.

override fun onTransitionCancel(transition: Transition) {}

override fun onTransitionStart(transition: Transition) {}
})
Copy link
Member

Choose a reason for hiding this comment

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

Could extend SimpleTransitionListener to avoid empty implementation.

android:layout_marginHorizontal="2dp"
android:background="@android:color/transparent"
android:contentDescription="@string/app_name">
<!-- The contentDescription attr is populated programmatically. This is just to fix lint issues. -->
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 want to add a tint, so that it works well on light and dark theme.

Copy link
Member Author

Choose a reason for hiding this comment

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

As replied above, the final designs will be implemented on another PR if that's fine.

@jmartinesp
Copy link
Member Author

jmartinesp commented Oct 10, 2022

Nice work! Quick smoke test with the RTE enabled, seems to work fine. The design will be updated? Could be nice to have something similar Element Web with popup:

image

The design that was chosen will keep this layout, we thought about using popups but they'd clash with Android native ones (copy, paste, select all, etc.) and there might not be room for all the options to include in the future.

The design will be updated in a future PR, adding background and tint colors to the buttons and other sizes and appearance adjustments.

@sonarcloud
Copy link

sonarcloud bot commented Oct 10, 2022

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 3 Code Smells

5.4% 5.4% Coverage
15.3% 15.3% Duplication

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!

@andybalaam
Copy link
Contributor

@bmarty since @jmartinesp is away, would you be able to merge this? Thanks!

@jmartinesp jmartinesp merged commit def67b2 into develop Oct 11, 2022
@jmartinesp jmartinesp deleted the tech/integrate-wysiwyg branch October 11, 2022 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants