Skip to content

Commit 9626801

Browse files
committed
Implement delete or update in PlaceholderManager.kt
1 parent 5c3dc57 commit 9626801

File tree

1 file changed

+65
-25
lines changed

1 file changed

+65
-25
lines changed

media-placeholders/src/main/java/org/wordpress/aztec/placeholders/PlaceholderManager.kt

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -116,43 +116,83 @@ class PlaceholderManager(
116116
).lastOrNull()
117117
val currentType = currentItem?.attributes?.getValue(TYPE_ATTRIBUTE)
118118
if (currentType != null && shouldMergeItem(currentType)) {
119-
val adapter = adapters[type]
120-
?: throw IllegalArgumentException("Adapter for inserted type not found. Register it with `registerAdapter` method")
121-
val currentAttributes = mutableMapOf<String, String>()
122-
val uuid = currentItem.attributes.getValue(UUID_ATTRIBUTE)
123-
for (i in 0 until currentItem.attributes.length) {
124-
val name = currentItem.attributes.getQName(i)
125-
val value = currentItem.attributes.getValue(name)
126-
currentAttributes[name] = value
127-
}
128-
val updatedAttributes = updateItem(currentAttributes, currentType)
129-
removeItem { aztecAttributes ->
130-
aztecAttributes.getValue(UUID_ATTRIBUTE) == uuid
131-
}
132-
val attrs = AztecAttributes().apply {
133-
updatedAttributes.forEach { (key, value) ->
134-
setValue(key, value)
135-
}
136-
}
137-
attrs.setValue(UUID_ATTRIBUTE, uuid)
138-
attrs.setValue(TYPE_ATTRIBUTE, type)
139-
val drawable = buildPlaceholderDrawable(adapter, attrs)
140-
aztecText.insertMediaSpan(AztecPlaceholderSpan(aztecText.context, drawable, 0, attrs,
141-
this, aztecText, WeakReference(adapter), TAG = htmlTag))
142-
insertContentOverSpanWithId(uuid)
119+
updateSpan(type, currentItem, updateItem, currentType)
143120
} else {
144121
insertItem(type, *updateItem(null, null).toList().toTypedArray())
145122
}
146123
}
147124

125+
private suspend fun updateSpan(
126+
type: String,
127+
currentItem: AztecPlaceholderSpan,
128+
updateItem: (currentAttributes: Map<String, String>, currentType: String) -> Map<String, String>,
129+
currentType: String
130+
) {
131+
val adapter = adapters[type]
132+
?: throw IllegalArgumentException("Adapter for inserted type not found. Register it with `registerAdapter` method")
133+
val currentAttributes = mutableMapOf<String, String>()
134+
val uuid = currentItem.attributes.getValue(UUID_ATTRIBUTE)
135+
for (i in 0 until currentItem.attributes.length) {
136+
val name = currentItem.attributes.getQName(i)
137+
val value = currentItem.attributes.getValue(name)
138+
currentAttributes[name] = value
139+
}
140+
val updatedAttributes = updateItem(currentAttributes, currentType)
141+
removeItem(uuid)
142+
val attrs = AztecAttributes().apply {
143+
updatedAttributes.forEach { (key, value) ->
144+
setValue(key, value)
145+
}
146+
}
147+
attrs.setValue(UUID_ATTRIBUTE, uuid)
148+
attrs.setValue(TYPE_ATTRIBUTE, type)
149+
val drawable = buildPlaceholderDrawable(adapter, attrs)
150+
aztecText.insertMediaSpan(AztecPlaceholderSpan(aztecText.context, drawable, 0, attrs,
151+
this, aztecText, WeakReference(adapter), TAG = htmlTag))
152+
insertContentOverSpanWithId(uuid)
153+
}
154+
155+
/**
156+
* Use this function to either update or remove an item. The decision whether to remove or update will be made
157+
* based upon the results of the parameter functions. An example of usage is a gallery of images. If the user wants
158+
* to remove one image in the gallery, they would call this method. If the removed image is one of many, they might
159+
* want to update the current parameters instead of removing the entire gallery. However, if the removed image is
160+
* the last one in the gallery, they will probably want to remove the entire gallery.
161+
* @param uuid UUID of the span we want to remove or update
162+
* @param shouldUpdateItem This function should return true if the span can be updated, false if it should be removed
163+
* @param updateItem Function that updates the selected item
164+
*/
165+
suspend fun removeOrUpdate(uuid: String, shouldUpdateItem: (Attributes) -> Boolean, updateItem: (currentAttributes: Map<String, String>) -> Map<String, String>): Boolean {
166+
val currentItem = aztecText.editableText.getSpans(0, aztecText.length(), AztecPlaceholderSpan::class.java).find {
167+
it.attributes.getValue(UUID_ATTRIBUTE) == uuid
168+
} ?: return false
169+
if (shouldUpdateItem(currentItem.attributes)) {
170+
val type = currentItem.attributes.getValue(TYPE_ATTRIBUTE)
171+
updateSpan(type, currentItem, updateItem = { attributes, _ ->
172+
updateItem(attributes)
173+
}, type)
174+
} else {
175+
removeItem(uuid)
176+
}
177+
return true
178+
}
179+
148180
/**
149-
* Call this method to remove a placeholder from both the AztecText and the overlaying layer programatically.
181+
* Call this method to remove a placeholder from both the AztecText and the overlaying layer programmatically.
150182
* @param predicate determines whether a span should be removed
151183
*/
152184
fun removeItem(predicate: (Attributes) -> Boolean) {
153185
aztecText.removeMedia { predicate(it) }
154186
}
155187

188+
/**
189+
* Call this method to remove a placeholder from both the AztecText and the overlaying layer programmatically.
190+
* @param uuid of the removed item
191+
*/
192+
fun removeItem(uuid: String) {
193+
aztecText.removeMedia { it.getValue(UUID_ATTRIBUTE) == uuid }
194+
}
195+
156196
private suspend fun buildPlaceholderDrawable(adapter: PlaceholderAdapter, attrs: AztecAttributes): Drawable {
157197
val drawable = ContextCompat.getDrawable(aztecText.context, android.R.color.transparent)!!
158198
updateDrawableBounds(adapter, attrs, drawable)

0 commit comments

Comments
 (0)