Skip to content

Commit

Permalink
Refactor isEditorEmpty to start emitting a value as soon a possible a…
Browse files Browse the repository at this point in the history
…nd have a default value of null
  • Loading branch information
LunarX committed Jul 11, 2024
1 parent b7f8e48 commit 3cf531a
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 17 deletions.
5 changes: 3 additions & 2 deletions rich-html-editor/src/main/assets/attach_listeners.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ document.addEventListener("selectionchange", () => {
focusCursorOnScreen()
})

onEmptyBodyChanges(isEditorEmpty => {
window.editor.onEmptyBodyChanges(isEditorEmpty)
reportEmptyBodyStatus()
onEditorChildListChange(() => {
reportEmptyBodyStatus()
})
21 changes: 10 additions & 11 deletions rich-html-editor/src/main/assets/define_listeners.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,10 @@ function getSelectionRangeOrNull() {
return (selection.rangeCount > 0) ? selection.getRangeAt(0) : null
}

function onEmptyBodyChanges(callback) {
function onEditorChildListChange(callback) {
let config = { childList: true }
let editor = getEditor()

var observer = new MutationObserver(_ => {
var isEditorEmpty = editor.childNodes.length === 0
if (previousEmptyStat === isEditorEmpty) return
previousEmptyStat = isEditorEmpty
callback(isEditorEmpty)
})

observer.observe(editor, config)
var observer = new MutationObserver(callback)
observer.observe(getEditor(), config)
}

// Core logic
Expand Down Expand Up @@ -144,3 +136,10 @@ function updateWebViewHeightWithBodyHeight() {

window.editor.reportNewDocumentHeight((documentElement.offsetHeight + paddingTop + paddingBottom) * window.devicePixelRatio)
}

function reportEmptyBodyStatus() {
var isEditorEmpty = getEditor().childNodes.length === 0
if (previousEmptyStat === isEditorEmpty) return
previousEmptyStat = isEditorEmpty
window.editor.onEmptyBodyChanges(isEditorEmpty)
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ internal class JsBridge(
)
val editorStatusesFlow: SharedFlow<EditorStatuses> = _editorStatusesFlow.asSharedFlow()

private var _isEmptyFlow: MutableStateFlow<Boolean> = MutableStateFlow(true)
var isEmptyFlow: StateFlow<Boolean> = _isEmptyFlow.asStateFlow()
private var _isEmptyFlow: MutableStateFlow<Boolean?> = MutableStateFlow(null)
var isEmptyFlow: StateFlow<Boolean?> = _isEmptyFlow.asStateFlow()

fun toggleBold() = execCommand(StatusCommand.BOLD)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,14 @@ class RichHtmlEditorWebView @JvmOverloads constructor(
*
* With some user inputs, the editor could visually look empty but still have a <br> or other tags inside it. In this case
* [isEmptyFlow] will still return false, so this value might not be suited for all usages.
*
* The flow is initialized to the value `null` until it receives its very first value from the javascript observer and won't
* ever become `null` again.
*
* If the flow emits a new value it will always be different than the previous value, i.e. it's already distinctUntilChanged
* by nature.
*/
val isEmptyFlow: StateFlow<Boolean> by jsBridge::isEmptyFlow
val isEmptyFlow: StateFlow<Boolean?> by jsBridge::isEmptyFlow

private var htmlExportCallback: MutableList<((html: String) -> Unit)> = mutableListOf()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.infomaniak.lib.richhtmleditor.Justification
import com.infomaniak.lib.richhtmleditor.sample.databinding.CreateLinkTextInputBinding
import com.infomaniak.lib.richhtmleditor.sample.databinding.FragmentEditorSampleBinding
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -68,6 +69,7 @@ class EditorSampleFragment : Fragment() {
setOnFocusChangeListener { _, hasFocus -> setToolbarEnabledStatus(hasFocus) }

isEmptyFlow
.filterNotNull()
.onEach { isEditorEmpty -> placeholder.isVisible = isEditorEmpty }
.launchIn(lifecycleScope)
}
Expand Down
4 changes: 3 additions & 1 deletion sample/src/main/res/layout/fragment_editor_sample.xml
Original file line number Diff line number Diff line change
Expand Up @@ -362,11 +362,13 @@
android:text="Write here"
android:textColor="@color/placeholderColor"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/webViewLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/webViewLayout" />
app:layout_constraintTop_toTopOf="@id/webViewLayout"
tools:visibility="visible" />

</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
Expand Down

0 comments on commit 3cf531a

Please sign in to comment.