-
Notifications
You must be signed in to change notification settings - Fork 15
feat: Add signature and quotes in RichHtmlEditorWebview #2811
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
Open
solrubado
wants to merge
94
commits into
main
Choose a base branch
from
rich-editor
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
94 commits
Select commit
Hold shift + click to select a range
8955bb7
feat: Add signature to rich editor
solrubado d2ed990
feat: Add signature and quotes to richHtlmEditorWebView
solrubado a802d2c
feat: Add everything into the mainwebview
solrubado 5b0f5e6
feat: Add everything in the same webview and add button to hide quotes
solrubado f7a6f36
feat: Changes in quote toggle button and in webview focus
solrubado 73019fa
refactor: Remove logs, unnused icon and use jsoupwithlogs
solrubado 6e2580b
fix: Add signature before quotes if they exist
solrubado 75c23ac
feat: Show images on forward
solrubado 7385a79
fix: Use images cids and remove loadWithOverviewMode on new message
solrubado 4d59bb0
refactor: Remove unnecesary log
solrubado d5957bf
refactor: Remove unused function
solrubado 7143acd
refactor: Fix identation in style css
solrubado 1b1bb1e
refactor: Fix sonar issues
solrubado cbe1862
feat: Add textview placeholder and change signature with js
solrubado 306f489
feat: Remove splitting of mail body if it's a draft and fix save snap…
solrubado 86f88c9
fix: Fix cid images and webclient for attachments
solrubado eb7f4fa
feat: Change 3 dots for text button and fix ai PR suggestions
solrubado cf78338
fix: Fix sonar issues and add more margin to signature
solrubado 38a7e31
refactor: Refactor for PR
solrubado f438f6a
fix: Remove unnecesary space
solrubado 698b303
fix: Fix PR comments
solrubado 6610621
fix: Fix PR comments
solrubado 8002a56
fix: Horizontal scroll in messages
solrubado 416fc8f
fix: Add horizontal scroll in messages
solrubado bc6da2d
feat: Add a EditorWebViewClient implementation as well
LunarX 834b836
fix: Fix snapshot and horizontal scroll in wide emails
solrubado 9ee38c3
fix: Change library version and fixes for configuration changes
solrubado a1728b7
refactor: Changes for PR
solrubado 59d42f5
fix: Make sure webview is ready before evaluating js
solrubado 6f90567
fix: Remove unnecesary margins in css and add margin to placeholder
solrubado 2fdb8e8
refactor: Add shimmering comment and check quotes visibility after init
solrubado 10ed7ba
refactor: Fix new lines for PR
solrubado 47d5106
fix: Remove unnused function
solrubado e6e5616
feat: Remove images from inline attachment if they are deleted from q…
solrubado 99e04ca
fix: Fix sonar issue
solrubado c876e3d
refactor: Refactor for PR
solrubado c5b636f
refactor: Add comment on munge script and add missing semicolons in q…
solrubado 11a6d51
fix: Fix signature update
solrubado 0ed1219
fix: Remove spellcheck in signature
solrubado 30d89f8
fix: Fix bodyHasQuotes functions
solrubado f6f4ca0
fix: Fix empty body logic and refactor
solrubado 2bdb58a
fix: Take into account blank characters when displaying placeholder
solrubado 7eef5d9
refactor: Use globalThis instead of window to follow standards
solrubado dc85c55
refactor: Remove unused strings
solrubado 2e05850
refactor: Extract javascript bridges to their own file
solrubado 7281147
fix: Clean webview client arguments and change inline images observer…
solrubado e928f8b
fix: Empty body sanitization, return kdoc and combine flows for quote…
solrubado 3605976
fix: Initialize webview client settings as soon as possible
solrubado 97c17d4
fix: Add signature ID used for replacing signature
solrubado 771c02c
fix: Fix snapshots that contain carriage returns
solrubado 9669516
fix: Use correct draft instance when saving snapshot
solrubado 2126294
fix: Make delete inline images script check the whole body
solrubado 717074c
fix: Signature replacement related to empty signature
solrubado 3ae1335
refactor: Move setupToggleQuotesButton to initUi
solrubado 45dc06a
fix: Use initial body to check placeholder visibility and sanitize in…
solrubado 70ff071
docs: Add comment on new line after quotes
solrubado 706a2c2
refactor: Body has empty quotes should avoid multiple parsing
solrubado 33ce1d1
fix: Extra padding on top of new message
solrubado d7eccbd
fix: Fix adding signature outside of editor when replacing a dummy si…
solrubado 9556b85
refactor: Correct methods' order in initDraftAndViewModel
solrubado d196f5e
fix: Add quotes to webview only when the user toggles their visibility
solrubado b0e6dc7
fix: Fix adding quotes if they are null
solrubado d784428
fix: Fix channel consumption
solrubado 370376c
fix: Fix body with null signature
solrubado c953928
fix: Add editor signature id if it is an existing draft
solrubado 178d00b
fix: Remove useless isBodyBlank jsoup parse
solrubado f2180be
fix: Only use 2 jsoup parse instead of 3
solrubado 222b8e7
fix: Not using body with signature id if the body didnt have quotes
solrubado 7c68a7a
refactor: Clean code a bit and add documentation
LunarX 4cea075
fix: Compare snapshots without EDITOR_LOCAL_SIGNATURE_ID
LunarX 3c1669b
fix: Split and save body, signature and quotes and fix snapshot
solrubado e3a5c81
refactor: Code refactor and copyrights update
solrubado f14f847
refactor: Remove unnecessary function getSanitizedHtml when the conte…
solrubado 87e2611
refactor: Save snapshot outside common body processing
LunarX 47fd588
refactor: Put back savesnapshot inside common body processing and ren…
LunarX 0512ae7
refactor: Change javascript bridge name
solrubado 563cb86
fix: Change mutable map for map
solrubado 8adaed2
refactor: Rename toggle button to show button
solrubado 461d6b4
refactor: Remove unnecessary comment
solrubado f1db35f
refactor: Remove unnecessary style
solrubado 5a61c06
refactor: Rename showQuotesScript to includeQuotesScript
solrubado ad4ddca
refactor: Refactor functions names, remove unnecessary is empty check…
solrubado 61f9181
docs: Explain why we need normalizeCarriageReturns
LunarX 7aeffe7
fix: Unnecessary new message check
solrubado 15b7660
fix: Fix editor when the email is generated by Euria
solrubado e1bab45
fix: Fix sonar recommendations in js script
solrubado 97f958b
feat: Add Matomo for when the user clicks on showQuote button
solrubado d5b2d2a
fix: JS string literal shouldnt be wrapped in quotes
solrubado d84a35f
refactor: Move BodyData class to MessageBodyUtils
solrubado 8f75fc3
fix: Don't duplicate shouldLoadResources in MessageDisplayWebViewClient
solrubado 0608720
chore: Update richHtmlEditor library
solrubado 3b5b9eb
fix: Add signature local id after split
solrubado efbcc8a
fix: Send saved elements as parameters in ai script
solrubado 2f82790
fix: Return all html after removing unwanted html
solrubado File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
app/src/main/java/com/infomaniak/mail/data/models/javascriptBridge/EditorJavascriptBridge.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| /* | ||
| * Infomaniak Mail - Android | ||
| * Copyright (C) 2026 Infomaniak Network SA | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
| package com.infomaniak.mail.data.models.javascriptBridge | ||
|
|
||
| import android.webkit.JavascriptInterface | ||
| import com.infomaniak.core.sentry.SentryLog | ||
| import org.json.JSONArray | ||
|
|
||
| class EditorJavascriptBridge( | ||
| private val onInlineImagesDeleted: (List<String>) -> Unit, | ||
| ) { | ||
| @JavascriptInterface | ||
| fun onInlineImagesDeleted(cidJson: String) { | ||
| val jsonArray = runCatching { | ||
| JSONArray(cidJson) | ||
| }.onFailure { | ||
| SentryLog.e(TAG, "Failed to parse CIDs", it) | ||
| }.getOrNull() ?: return | ||
|
|
||
| val cids = (0 until jsonArray.length()).map { jsonArray.getString(it) } | ||
| onInlineImagesDeleted(cids) | ||
| } | ||
|
|
||
| companion object { | ||
| private const val TAG = "EditorJavascriptBridge" | ||
| } | ||
| } |
59 changes: 59 additions & 0 deletions
59
...n/java/com/infomaniak/mail/data/models/javascriptBridge/MessageDisplayJavascriptBridge.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| /* | ||
| * Infomaniak Mail - Android | ||
| * Copyright (C) 2026 Infomaniak Network SA | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
| package com.infomaniak.mail.data.models.javascriptBridge | ||
|
|
||
| import android.webkit.JavascriptInterface | ||
| import com.infomaniak.mail.utils.SentryDebug | ||
|
|
||
| class MessageDisplayJavascriptBridge( | ||
| private val onWebViewFinishedLoading: () -> Unit, | ||
| ) { | ||
|
|
||
| @JavascriptInterface | ||
| fun reportOverScroll(clientWidth: Int, scrollWidth: Int, messageUid: String) { | ||
| SentryDebug.sendOverScrolledMessage(clientWidth, scrollWidth, messageUid) | ||
| } | ||
|
|
||
| @JavascriptInterface | ||
| fun reportError( | ||
| errorName: String, | ||
| errorMessage: String, | ||
| errorStack: String, | ||
| scriptFirstLine: String, | ||
| messageUid: String, | ||
| ) { | ||
| val correctErrorStack = fixStackTraceLineNumber(errorStack, scriptFirstLine) | ||
| SentryDebug.sendJavaScriptError(errorName, errorMessage, correctErrorStack, messageUid) | ||
| } | ||
|
|
||
| @JavascriptInterface | ||
| fun webviewFinishedLoading() { | ||
| onWebViewFinishedLoading() | ||
| } | ||
|
|
||
| private fun fixStackTraceLineNumber(errorStack: String, scriptFirstLine: String): String { | ||
| var correctErrorStack = errorStack | ||
| val matches = "about:blank:([0-9]+):".toRegex().findAll(correctErrorStack) | ||
| matches.forEach { match -> | ||
| val lineNumber = match.groupValues[1] | ||
| val newLineNumber = lineNumber.toInt() - scriptFirstLine.toInt() + 1 | ||
| correctErrorStack = correctErrorStack.replace(match.groupValues[0], "about:blank:$newLineNumber:") | ||
| } | ||
| return correctErrorStack | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
app/src/main/java/com/infomaniak/mail/ui/main/thread/webViewClient/EditorWebViewClient.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| /* | ||
| * Infomaniak Mail - Android | ||
| * Copyright (C) 2026 Infomaniak Network SA | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
| package com.infomaniak.mail.ui.main.thread.webViewClient | ||
|
|
||
| import android.content.Context | ||
| import android.webkit.WebView | ||
| import com.infomaniak.mail.data.models.Attachment | ||
|
|
||
| class EditorWebViewClient( | ||
| context: Context, | ||
| cidDictionary: Map<String, Attachment>, | ||
| shouldLoadDistantResources: Boolean, | ||
| private val onPageFinished: () -> Unit, | ||
| ) : MessageWebViewClient( | ||
| context, | ||
| cidDictionary, | ||
| shouldLoadDistantResources, | ||
| ) { | ||
| override fun onPageFinished(webView: WebView, url: String?) { | ||
| onPageFinished() | ||
| } | ||
| } |
94 changes: 94 additions & 0 deletions
94
...main/java/com/infomaniak/mail/ui/main/thread/webViewClient/MessageDisplayWebViewClient.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| /* | ||
| * Infomaniak Mail - Android | ||
| * Copyright (C) 2026 Infomaniak Network SA | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
| package com.infomaniak.mail.ui.main.thread.webViewClient | ||
|
|
||
| import android.content.Context | ||
| import android.content.Intent | ||
| import android.net.Uri | ||
| import android.webkit.WebResourceRequest | ||
| import android.webkit.WebView | ||
| import com.infomaniak.core.ui.showToast | ||
| import com.infomaniak.core.ui.view.toDp | ||
| import com.infomaniak.lib.richhtmleditor.looselyEscapeAsStringLiteralForJs | ||
| import com.infomaniak.mail.R | ||
| import com.infomaniak.mail.data.models.Attachment | ||
| import com.infomaniak.mail.utils.Utils.runCatchingRealm | ||
| import com.infomaniak.mail.utils.WebViewVersionUtils | ||
| import io.sentry.Sentry | ||
| import io.sentry.SentryLevel | ||
|
|
||
| class MessageDisplayWebViewClient( | ||
| private val context: Context, | ||
| cidDictionary: Map<String, Attachment>, | ||
| private val messageUid: String, | ||
| shouldLoadDistantResources: Boolean, | ||
| onBlockedResourcesDetected: () -> Unit, | ||
| private val navigateToNewMessageActivity: ((Uri) -> Unit)?, | ||
| private val onPageFinished: (() -> Unit)?, | ||
| ) : MessageWebViewClient( | ||
| context, | ||
| cidDictionary, | ||
| shouldLoadDistantResources, | ||
| onBlockedResourcesDetected, | ||
| ) { | ||
| override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { | ||
| request.url?.let { uri -> | ||
|
|
||
| if (uri.scheme == "mailto") { | ||
| navigateToNewMessageActivity?.invoke(uri) | ||
| return true | ||
| } | ||
|
|
||
| runCatching { | ||
| val intent = Intent(Intent.ACTION_VIEW, uri) | ||
| intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) | ||
| context.startActivity(intent) | ||
| }.onFailure { | ||
| context.showToast(R.string.startActivityCantHandleAction) | ||
| } | ||
| } | ||
| return true | ||
| } | ||
|
|
||
| override fun onPageFinished(webView: WebView, url: String?) { | ||
| runCatchingRealm { | ||
| val widthInDp = webView.width.toDp(webView) | ||
| if (widthInDp <= 0) { | ||
| val versionData = WebViewVersionUtils.getWebViewVersionData(context) | ||
|
|
||
| Sentry.captureMessage("Zero width webview detected onPageFinished which prevents message width's normalization") { scope -> | ||
| scope.level = SentryLevel.WARNING | ||
| scope.setExtra("width", webView.width.toString()) | ||
| scope.setExtra("measuredWidth", webView.measuredWidth.toString()) | ||
| scope.setExtra("height", webView.height.toString()) | ||
| scope.setExtra("measuredHeight", webView.measuredHeight.toString()) | ||
| scope.setTag( | ||
| "webview version", | ||
| "${versionData?.webViewPackageName}: ${versionData?.versionName} - ${versionData?.majorVersion}" | ||
| ) | ||
| scope.setTag("visibility", webView.visibility.toString()) | ||
| scope.setTag("messageUid", messageUid) | ||
| scope.setTag("shouldLoadDistantResources", shouldLoadDistantResources.toString()) | ||
| } | ||
| } | ||
| val escapedMessageUid = looselyEscapeAsStringLiteralForJs(messageUid) | ||
| webView.loadUrl("javascript:removeAllProperties(); normalizeMessageWidth($widthInDp, $escapedMessageUid)") | ||
| onPageFinished?.invoke() | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.