Skip to content

Commit

Permalink
Merge pull request #168 from MohamedRejeb/1.x
Browse files Browse the repository at this point in the history
Fix long click crash on Android and iOS
  • Loading branch information
MohamedRejeb authored Dec 31, 2023
2 parents 1fa8b5d + d2d8d42 commit 1a87d96
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 22 deletions.
8 changes: 3 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
#Gradle
org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M"
org.gradle.caching=true
org.gradle.parallel=true

#Kotlin
kotlin.code.style=official

#MPP
kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.mpp.enableCInteropCommonization=true

#Android
android.useAndroidX=true
android.nonTransitiveRClass=true

#Web
kotlin.js.compiler=ir
org.jetbrains.compose.experimental.jscanvas.enabled=true

#iOS
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.mohamedrejeb.richeditor.platform

internal actual val currentPlatform: Platform = Platform.Android
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,17 @@ import com.mohamedrejeb.richeditor.annotation.ExperimentalRichTextApi
import com.mohamedrejeb.richeditor.model.RichParagraph.Type.Companion.startText
import com.mohamedrejeb.richeditor.parser.html.RichTextStateHtmlParser
import com.mohamedrejeb.richeditor.parser.markdown.RichTextStateMarkdownParser
import com.mohamedrejeb.richeditor.platform.currentPlatform
import com.mohamedrejeb.richeditor.utils.*
import com.mohamedrejeb.richeditor.utils.append
import com.mohamedrejeb.richeditor.utils.customMerge
import com.mohamedrejeb.richeditor.utils.isSpecifiedFieldsEquals
import com.mohamedrejeb.richeditor.utils.unmerge
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import kotlin.math.max

@Composable
Expand Down Expand Up @@ -506,6 +511,21 @@ class RichTextState internal constructor(
updateParagraphType(paragraph, RichParagraph.Type.Default)
}

private val textFieldValueSharedFlow = MutableSharedFlow<TextFieldValue>()

internal suspend fun emitTextFieldValue(textFieldValue: TextFieldValue) {
textFieldValueSharedFlow.emit(textFieldValue)
}

internal var collectTextFieldValueSharedFlowJob: Job? = null
internal suspend fun collectTextFieldValueSharedFlow() = coroutineScope {
collectTextFieldValueSharedFlowJob = launch {
textFieldValueSharedFlow.collect { newTextFieldValue ->
onTextFieldValueChange(newTextFieldValue)
}
}
}

/**
* Temporarily stores the new text field value, before it is validated.
*/
Expand All @@ -517,6 +537,11 @@ class RichTextState internal constructor(
* @param newTextFieldValue the new text field value.
*/
internal fun onTextFieldValueChange(newTextFieldValue: TextFieldValue) {
println("onTextFieldValueChange: ${newTextFieldValue.text.replace("\n", "<br/>")}")
println("same text field value: ${newTextFieldValue == tempTextFieldValue}")
println("same text: ${newTextFieldValue.text == tempTextFieldValue.text}")
println("same selection: ${newTextFieldValue.selection == tempTextFieldValue.selection}")
if (newTextFieldValue == tempTextFieldValue) return
tempTextFieldValue = newTextFieldValue

if (tempTextFieldValue.text.length > textFieldValue.text.length)
Expand Down Expand Up @@ -576,6 +601,12 @@ class RichTextState internal constructor(

// Clear [tempTextFieldValue]
tempTextFieldValue = TextFieldValue()

println("end edit")
richParagraphList.forEachIndexed { index, paragraph ->
println("Paragraph: $index")
println(paragraph.toString())
}
}

/**
Expand Down Expand Up @@ -628,7 +659,12 @@ class RichTextState internal constructor(

// Add empty space to the last paragraph if it's empty.
// Workaround to fix an issue with Compose TextField that causes a crash on long click
if (i > 0 && i == richParagraphList.lastIndex && richParagraph.isEmpty()) {
if (
(currentPlatform.isAndroid ||
currentPlatform.isIOS) &&
i > 0 && i == richParagraphList.lastIndex &&
richParagraph.isEmpty()
) {
richParagraph.getFirstNonEmptyChild()?.text = " "
append(" ")
index++
Expand Down Expand Up @@ -1027,6 +1063,10 @@ class RichTextState internal constructor(
val sliceIndex = max(index, richSpan.textRange.min)

// Create a new paragraph style

println("oldParagraphType: ${richSpan.paragraph.type}")
println("oldParagraphStartText: ${richSpan.paragraph.type.startText}")

val newParagraph = richSpan.paragraph.slice(
startIndex = sliceIndex,
richSpan = richSpan,
Expand All @@ -1050,6 +1090,10 @@ class RichTextState internal constructor(

// Update the paragraph type of the paragraphs after the new paragraph
val newParagraphType = newParagraph.type

println("newParagraphType: $newParagraphType")
println("newParagraphStartText: ${newParagraphType.startText}")

if (newParagraphType is RichParagraph.Type.OrderedList) {
tempTextFieldValue = adjustOrderedListsNumbers(
startParagraphIndex = paragraphIndex + 2,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.mohamedrejeb.richeditor.platform

internal enum class Platform {
Android, IOS, Desktop, Web;

val isAndroid: Boolean
get() = this == Android

val isIOS: Boolean
get() = this == IOS

val isDesktop: Boolean
get() = this == Desktop

val isWeb: Boolean
get() = this == Web
}

internal expect val currentPlatform: Platform
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import androidx.compose.ui.unit.sp
import com.mohamedrejeb.richeditor.model.RichParagraph
import com.mohamedrejeb.richeditor.model.RichTextState
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch


/**
Expand Down Expand Up @@ -197,6 +198,7 @@ internal fun BasicRichTextEditor(
@Composable { innerTextField -> innerTextField() },
contentPadding: PaddingValues
) {
val scope = rememberCoroutineScope()
val density = LocalDensity.current
val localTextStyle = LocalTextStyle.current
val layoutDirection = LocalLayoutDirection.current
Expand Down Expand Up @@ -233,12 +235,25 @@ internal fun BasicRichTextEditor(
}
}

DisposableEffect(state) {
scope.launch {
state.collectTextFieldValueSharedFlow()
}

onDispose {
state.collectTextFieldValueSharedFlowJob?.cancel()
}
}

CompositionLocalProvider(LocalClipboardManager provides richClipboardManager) {
BasicTextField(
value = state.textFieldValue,
onValueChange = {
if (readOnly) return@BasicTextField
if (it.text.length > maxLength) return@BasicTextField
// scope.launch {
// state.emitTextFieldValue(it)
// }
state.onTextFieldValueChange(it)
},
modifier = modifier
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.mohamedrejeb.richeditor.platform

internal actual val currentPlatform: Platform = Platform.Desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.mohamedrejeb.richeditor.platform

internal actual val currentPlatform: Platform = Platform.IOS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.mohamedrejeb.richeditor.platform

internal actual val currentPlatform: Platform = Platform.Web
Binary file not shown.
8 changes: 6 additions & 2 deletions sample/web/src/jsMain/kotlin/Main.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.CanvasBasedWindow
import com.mohamedrejeb.richeditor.sample.common.App
import org.jetbrains.skiko.wasm.onWasmReady

@OptIn(ExperimentalComposeUiApi::class)
fun main() {
onWasmReady {
Window("Compose Rich Editor") {
CanvasBasedWindow(
title = "Compose Rich Editor"
) {
Box(Modifier.fillMaxSize()) {
App()
}
Expand Down
23 changes: 9 additions & 14 deletions sample/web/src/jsMain/resources/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,17 @@
<head>
<meta charset="UTF-8">
<title>Compose Rich Editor</title>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
<script src="skiko.js"></script>
</head>
<body>
<canvas id="ComposeTarget"></canvas>
<script>
var canvas = document.getElementById("ComposeTarget");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
</script>
<script src="skiko.js"></script>
<noscript>
This page requires JavaScript.
</noscript>
<div id="root" class="d-flex flex-column h-100">
</div>
<div>
<canvas id="ComposeTarget" width="800" height="600"></canvas>
</div>
<script src="web.js"></script>
</body>
</html>
Empty file removed sample/web/webpack.config.d/fs.js
Empty file.

0 comments on commit 1a87d96

Please sign in to comment.