Skip to content

Forms : Consume latest api #506

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

Merged
merged 7 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ ignoreBuildNumber=false
# these versions define the dependency of the ArcGIS Maps SDK for Kotlin dependency
# and are generally not overridden at the command line unless a special build is requested.
sdkVersionNumber=200.5.0
sdkBuildNumber=4273
sdkBuildNumber=4297
Original file line number Diff line number Diff line change
Expand Up @@ -185,22 +185,28 @@ class MapViewModel @Inject constructor(
)
// if there are no errors then update the feature
return if (errors.isEmpty()) {
val feature = featureForm.feature
val serviceFeatureTable =
feature.featureTable as? ServiceFeatureTable ?: return Result.failure(
featureForm.feature.featureTable as? ServiceFeatureTable ?: return Result.failure(
IllegalStateException("cannot save feature edit without a ServiceFeatureTable")
)
val result = featureForm.finishEditing().map {
var result = Result.success(Unit)
featureForm.finishEditing().onSuccess {
serviceFeatureTable.serviceGeodatabase?.let { database ->
return@let if (database.serviceInfo?.canUseServiceGeodatabaseApplyEdits == true) {
database.applyEdits()
if (database.serviceInfo?.canUseServiceGeodatabaseApplyEdits == true) {
database.applyEdits().onFailure {
result = Result.failure(it)
}
} else {
serviceFeatureTable.applyEdits()
serviceFeatureTable.applyEdits().onFailure {
result = Result.failure(it)
}
}
}
feature.refresh()
featureForm.feature.refresh()
// unselect the feature after the edits have been saved
(feature.featureTable?.layer as FeatureLayer).clearSelection()
(featureForm.feature.featureTable?.layer as FeatureLayer).clearSelection()
}.onFailure {
result = Result.failure(it)
}
// set the state to not editing since the feature was updated successfully
_uiState.value = UIState.NotEditing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ internal class AttachmentElementState(
*/
private fun buildAttachmentStates(list: List<FormAttachment>) {
attachments.clear()
list.forEach { formAttachment ->
list.asReversed().forEach { formAttachment ->
// create a new state
val state = FormAttachmentState(
name = formAttachment.name,
Expand All @@ -131,7 +131,7 @@ internal class AttachmentElementState(
// if the attachment is already loaded then re-load the new state
// this is useful during a configuration change when the form attachment
// objects have already been loaded by the state object.
if (formAttachment.loadStatus.value is LoadStatus.Loaded) {
if (formAttachment.loadStatus.value is LoadStatus.Loaded || formAttachment.isLocal) {
state.loadWithParentScope()
}
attachments.add(state)
Expand All @@ -141,8 +141,9 @@ internal class AttachmentElementState(
/**
* Adds an attachment with the given [name], [contentType], and [data].
*/
fun addAttachment(name: String, contentType: String, data: ByteArray) {
val formAttachment = formElement.addAttachment(name, contentType, data)
fun addAttachment(name: String, contentType: String, data: ByteArray): Result<Unit> {
val formAttachment = formElement.addAttachmentOrNull(name, contentType, data)
?: return Result.failure(Exception("Failed to add attachment"))
// create a new state
val state = FormAttachmentState(
name = formAttachment.name,
Expand All @@ -165,6 +166,7 @@ internal class AttachmentElementState(
lazyListState.scrollToItem(0)
evaluateExpressions()
}
return Result.success(Unit)
}

/**
Expand Down Expand Up @@ -402,11 +404,8 @@ internal class FormAttachmentState(
val bitmap = try {
when (type) {
is FormAttachmentType.Image -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ThumbnailUtils.createImageThumbnail(File(filePath), thumbnailSize, null)
} else {
ThumbnailUtils.createImageThumbnail(filePath, 1)
}
formAttachment.createThumbnail(thumbnailSize.width, thumbnailSize.height)
.getOrThrow().bitmap
}

FormAttachmentType.Video -> {
Expand Down Expand Up @@ -521,9 +520,16 @@ internal fun FormAttachmentType.getIcon(): ImageVector = when (this) {
}

/**
* Returns a new attachment name based on the content type.
* Returns a new attachment name based on the [contentType] and [extension].
*
* @param contentType The content type of the attachment.
* @param extension The file extension of the attachment.
* @return A new attachment name including the file extension specified by [extension].
*/
internal fun AttachmentElementState.getNewAttachmentNameForContentType(contentType: String): String {
internal fun AttachmentElementState.getNewAttachmentNameForContentType(
contentType: String,
extension: String
): String {
// use the content type prefix to generate a new attachment name
val prefix = contentType.split("/").firstOrNull()?.replaceFirstChar(Char::titlecase)
?: "Attachment"
Expand All @@ -533,8 +539,8 @@ internal fun AttachmentElementState.getNewAttachmentNameForContentType(contentTy
} + 1
// create a set of attachment names to check for duplicates
val names = attachments.mapTo(hashSetOf()) { it.name }
while (names.contains("${prefix}$count")) {
while (names.contains("${prefix}$count.$extension")) {
count++
}
return "${prefix}$count"
return "${prefix}$count.$extension"
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ internal fun AttachmentTile(
onClick = {
showContextMenu = false
state.deleteAttachment()
Toast.makeText(context, context.getString(R.string.attachment_deleted, state.name), Toast.LENGTH_SHORT).show()
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ private suspend fun AttachmentElementState.addAttachmentFromUri(
return@withContext Result.failure(Exception(context.getString(R.string.attachment_error)))
}
// generate a name for the attachment
var name = "${getNewAttachmentNameForContentType(contentType)}.$extension"
var name = getNewAttachmentNameForContentType(contentType, extension)
// size of the attachment
var size = 0L
// get the name and size of the attachment
Expand Down Expand Up @@ -417,7 +417,7 @@ private suspend fun AttachmentElementState.addAttachmentFromUri(
context.readBytes(uri).onFailure {
result = Result.failure(it)
}.onSuccess { data ->
addAttachment(name, contentType, data)
result = addAttachment(name, contentType, data)
}
result
}
Expand Down
1 change: 1 addition & 0 deletions toolkit/featureforms/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,5 @@
<string name="attachment_too_large">The File is too large. Please add a file less than 50 MB.</string>
<string name="attachment_is_empty">Empty files are not supported</string>
<string name="download_empty_file">Empty files cannot be downloaded</string>
<string name="attachment_deleted">%1s was deleted successfully</string>
</resources>