Skip to content

Commit

Permalink
Fix for "This item has been changed remotely. It will now reload." di…
Browse files Browse the repository at this point in the history
…alog appearing on ItemDetailsScreen not only when item was changed remotely, but also every time user changed any field on the device.

Adding 500 ms debounce to Abstract text field, to reduce number of DB Request when user is inputting data.

Upping versionCode to 86
  • Loading branch information
Dima-Android committed Aug 1, 2024
1 parent 8ab234d commit b32cfa5
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ internal fun ItemDetailsEditScreen(
)
if (!viewState.data.isAttachment) {
EditAbstractRow(
detailValue = viewState.data.abstract ?: "",
onValueChange = viewModel::onAbstractEdit
detailValue = viewState.abstractText,
onValueChange = viewModel::onAbstractTextChange
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import org.zotero.android.database.objects.Attachment
import org.zotero.android.database.objects.FieldKeys
import org.zotero.android.database.objects.ItemTypes
import org.zotero.android.database.objects.RItem
import org.zotero.android.database.objects.UpdatableChangeType
import org.zotero.android.database.requests.CancelParentCreationDbRequest
import org.zotero.android.database.requests.CreateAttachmentsDbRequest
import org.zotero.android.database.requests.CreateItemFromDetailDbRequest
Expand Down Expand Up @@ -208,6 +207,7 @@ class ItemDetailsViewModel @Inject constructor(
EventBus.getDefault().register(this)
setupFileObservers()
setupOnFieldValueTextChangeFlow()
setupOnAbstractTextChangeFlow()

val args = ScreenArguments.itemDetailsArgs

Expand Down Expand Up @@ -292,7 +292,8 @@ class ItemDetailsViewModel @Inject constructor(
type = type,
userId = userId,
library = library,
preScrolledChildKey = preScrolledChildKey
preScrolledChildKey = preScrolledChildKey,
abstractText = viewState.data.abstract ?: ""
)
}
conflictResolutionUseCase.currentlyDisplayedItemLibraryIdentifier = viewState.library?.identifier
Expand All @@ -316,6 +317,7 @@ class ItemDetailsViewModel @Inject constructor(
snapshot = updatedStateData,
data = updatedData,
isEditing = true,
abstractText = updatedData.abstract ?: ""
)
}
}
Expand Down Expand Up @@ -471,7 +473,10 @@ class ItemDetailsViewModel @Inject constructor(
isEditing: Boolean,
) {
updateState {
copy(data = data)
copy(
data = data,
abstractText = data.abstract ?: ""
)
}
if (viewState.snapshot != null || isEditing) {
val updatedSnapshot = data.deepCopy(
Expand Down Expand Up @@ -508,10 +513,17 @@ class ItemDetailsViewModel @Inject constructor(
}
}

private var ignoreScreenRefreshOnNextDbUpdate: Boolean = false

private fun shouldReloadData(item: RItem, changes: Array<String>): Boolean {
if (changes.contains("version")) {
//Use old value?
if (changes.contains("changeType") && item.changeType != UpdatableChangeType.user.name) {
if (changes.contains("changeType")) {
//Unfortunately there is no way on Android's RealmDB to get the previous value of RealmObject's 'changeType' field in it's ChangeListener.
// That's why we have to adjust shouldReloadData logic to ignore user's input during DB Refresh with this flag.
if (ignoreScreenRefreshOnNextDbUpdate) {
ignoreScreenRefreshOnNextDbUpdate = false
return false
}
return true
}
return false
Expand Down Expand Up @@ -622,6 +634,29 @@ class ItemDetailsViewModel @Inject constructor(
}
}

private var onAbstractTextChangeFlow = MutableStateFlow<String?>(null)

private fun setupOnAbstractTextChangeFlow() {
onAbstractTextChangeFlow
.debounce(500)
.map { data ->
if (data != null) {
onAbstractEdit(data)
}
}
.launchIn(viewModelScope)
}

fun onAbstractTextChange(newAbstract: String) {
updateState {
copy(
abstractText = newAbstract
)
}
onAbstractTextChangeFlow.tryEmit(newAbstract)
}


private var onFieldValueTextChangeFlow = MutableStateFlow<Pair<String, String>?>(null)

private fun setupOnFieldValueTextChangeFlow() {
Expand Down Expand Up @@ -661,6 +696,7 @@ class ItemDetailsViewModel @Inject constructor(
if (field == null) {
return
}
ignoreScreenRefreshOnNextDbUpdate = true

field.value = value
field.isTappable = ItemDetailDataCreator.isTappable(
Expand Down Expand Up @@ -740,7 +776,8 @@ class ItemDetailsViewModel @Inject constructor(
}
}

fun onAbstractEdit(newAbstract: String) {
private fun onAbstractEdit(newAbstract: String) {
ignoreScreenRefreshOnNextDbUpdate = true
val updatedData = viewState.data.deepCopy(abstract = newAbstract)
updateState {
copy(data = updatedData)
Expand Down Expand Up @@ -801,6 +838,7 @@ class ItemDetailsViewModel @Inject constructor(
}

private fun endEditing() {
ignoreScreenRefreshOnNextDbUpdate = false
if (viewState.snapshot == viewState.data) {
return
}
Expand Down Expand Up @@ -878,7 +916,8 @@ class ItemDetailsViewModel @Inject constructor(
snapshot = null,
isEditing = false,
type = DetailType.preview(viewState.key),
data = updatedData
data = updatedData,
abstractText = updatedData.abstract ?: ""
)
}
}
Expand Down Expand Up @@ -2036,6 +2075,7 @@ data class ItemDetailsViewState(
val longPressOptionsHolder: LongPressOptionsHolder? = null,
val fieldFocusKey: String? = null,
val fieldFocusText: String = "",
val abstractText: String = "",
) : ViewState

sealed class ItemDetailsViewEffect : ViewEffect {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ internal fun ItemDetailsViewScreen(
showDivider = false
)

if (!viewState.data.isAttachment) {
if (!viewState.data.isAttachment && !viewState.data.abstract.isNullOrBlank()) {
CustomDivider(
modifier = Modifier
.padding(top = 4.dp)
Expand Down
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/BuildConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ object BuildConfig {
const val compileSdkVersion = 34
const val targetSdk = 34

val versionCode = 85 // Must be updated on every build
val versionCode = 86 // Must be updated on every build
val version = Version(
major = 1,
minor = 0,
Expand Down

0 comments on commit b32cfa5

Please sign in to comment.