3486: Separate diff and encoding

This commit is contained in:
Lakoja 2023-08-22 16:12:03 +02:00
parent f09f464667
commit ba50ff5686
1 changed files with 54 additions and 35 deletions

View File

@ -114,16 +114,37 @@ class EditProfileViewModel @Inject constructor(
saveData.value = Loading() saveData.value = Loading()
val diff = getProfileDiff(apiProfileAccount, newProfileData) val diff = getProfileDiff(apiProfileAccount, newProfileData)
if (diff.hasNoChanges()) { if (!diff.hasChanges()) {
// if nothing has changed, there is no need to make an api call // if nothing has changed, there is no need to make an api call
saveData.postValue(Success()) saveData.postValue(Success())
return return
} }
viewModelScope.launch { viewModelScope.launch {
var avatarFileBody: MultipartBody.Part? = null
diff.avatarFile?.let {
avatarFileBody = MultipartBody.Part.createFormData("avatar", randomAlphanumericString(12), it.asRequestBody("image/png".toMediaTypeOrNull()))
}
var headerFileBody: MultipartBody.Part? = null
diff.headerFile?.let {
headerFileBody = MultipartBody.Part.createFormData("header", randomAlphanumericString(12), it.asRequestBody("image/png".toMediaTypeOrNull()))
}
mastodonApi.accountUpdateCredentials( mastodonApi.accountUpdateCredentials(
diff.displayName, diff.note, diff.locked, diff.avatar, diff.header, diff.displayName?.toRequestBody(MultipartBody.FORM),
diff.field1?.first, diff.field1?.second, diff.field2?.first, diff.field2?.second, diff.field3?.first, diff.field3?.second, diff.field4?.first, diff.field4?.second diff.note?.toRequestBody(MultipartBody.FORM),
diff.locked?.toString()?.toRequestBody(MultipartBody.FORM),
avatarFileBody,
headerFileBody,
diff.field1?.first?.toRequestBody(MultipartBody.FORM),
diff.field1?.second?.toRequestBody(MultipartBody.FORM),
diff.field2?.first?.toRequestBody(MultipartBody.FORM),
diff.field2?.second?.toRequestBody(MultipartBody.FORM),
diff.field3?.first?.toRequestBody(MultipartBody.FORM),
diff.field3?.second?.toRequestBody(MultipartBody.FORM),
diff.field4?.first?.toRequestBody(MultipartBody.FORM),
diff.field4?.second?.toRequestBody(MultipartBody.FORM),
).fold( ).fold(
{ newAccountData -> { newAccountData ->
saveData.postValue(Success()) saveData.postValue(Success())
@ -152,62 +173,60 @@ class EditProfileViewModel @Inject constructor(
internal fun hasUnsavedChanges(newProfileData: ProfileData): Boolean { internal fun hasUnsavedChanges(newProfileData: ProfileData): Boolean {
val diff = getProfileDiff(apiProfileAccount, newProfileData) val diff = getProfileDiff(apiProfileAccount, newProfileData)
// If all fields are null, there are no changes.
return !diff.hasNoChanges() return diff.hasChanges()
} }
private fun getProfileDiff(oldProfileAccount: Account?, newProfileData: ProfileData): DiffProfileData { private fun getProfileDiff(oldProfileAccount: Account?, newProfileData: ProfileData): DiffProfileData {
val displayName = if (oldProfileAccount?.displayName == newProfileData.displayName) { val displayName = if (oldProfileAccount?.displayName == newProfileData.displayName) {
null null
} else { } else {
newProfileData.displayName.toRequestBody(MultipartBody.FORM) newProfileData.displayName
} }
val note = if (oldProfileAccount?.source?.note == newProfileData.note) { val note = if (oldProfileAccount?.source?.note == newProfileData.note) {
null null
} else { } else {
newProfileData.note.toRequestBody(MultipartBody.FORM) newProfileData.note
} }
val locked = if (oldProfileAccount?.locked == newProfileData.locked) { val locked = if (oldProfileAccount?.locked == newProfileData.locked) {
null null
} else { } else {
newProfileData.locked.toString().toRequestBody(MultipartBody.FORM) newProfileData.locked
} }
val avatar = if (avatarData.value != null) { val avatarFile = if (avatarData.value != null) {
val avatarBody = getCacheFileForName(AVATAR_FILE_NAME).asRequestBody("image/png".toMediaTypeOrNull()) getCacheFileForName(AVATAR_FILE_NAME)
MultipartBody.Part.createFormData("avatar", randomAlphanumericString(12), avatarBody)
} else { } else {
null null
} }
val header = if (headerData.value != null) { val headerFile = if (headerData.value != null) {
val headerBody = getCacheFileForName(HEADER_FILE_NAME).asRequestBody("image/png".toMediaTypeOrNull()) getCacheFileForName(HEADER_FILE_NAME)
MultipartBody.Part.createFormData("header", randomAlphanumericString(12), headerBody)
} else { } else {
null null
} }
// when one field changed, all have to be sent or they unchanged ones would get overridden // when one field changed, all have to be sent or they unchanged ones would get overridden
val fieldsUnchanged = oldProfileAccount?.source?.fields == newProfileData.fields val allFieldsUnchanged = oldProfileAccount?.source?.fields == newProfileData.fields
val field1 = calculateFieldToUpdate(newProfileData.fields.getOrNull(0), fieldsUnchanged) val field1 = calculateFieldToUpdate(newProfileData.fields.getOrNull(0), allFieldsUnchanged)
val field2 = calculateFieldToUpdate(newProfileData.fields.getOrNull(1), fieldsUnchanged) val field2 = calculateFieldToUpdate(newProfileData.fields.getOrNull(1), allFieldsUnchanged)
val field3 = calculateFieldToUpdate(newProfileData.fields.getOrNull(2), fieldsUnchanged) val field3 = calculateFieldToUpdate(newProfileData.fields.getOrNull(2), allFieldsUnchanged)
val field4 = calculateFieldToUpdate(newProfileData.fields.getOrNull(3), fieldsUnchanged) val field4 = calculateFieldToUpdate(newProfileData.fields.getOrNull(3), allFieldsUnchanged)
return DiffProfileData( return DiffProfileData(
displayName, note, locked, field1, field2, field3, field4, header, avatar displayName, note, locked, field1, field2, field3, field4, headerFile, avatarFile
) )
} }
private fun calculateFieldToUpdate(newField: StringField?, fieldsUnchanged: Boolean): Pair<RequestBody, RequestBody>? { private fun calculateFieldToUpdate(newField: StringField?, fieldsUnchanged: Boolean): Pair<String, String>? {
if (fieldsUnchanged || newField == null) { if (fieldsUnchanged || newField == null) {
return null return null
} }
return Pair( return Pair(
newField.name.toRequestBody(MultipartBody.FORM), newField.name,
newField.value.toRequestBody(MultipartBody.FORM) newField.value,
) )
} }
@ -216,18 +235,18 @@ class EditProfileViewModel @Inject constructor(
} }
private data class DiffProfileData( private data class DiffProfileData(
val displayName: RequestBody?, val displayName: String?,
val note: RequestBody?, val note: String?,
val locked: RequestBody?, val locked: Boolean?,
val field1: Pair<RequestBody, RequestBody>?, val field1: Pair<String, String>?,
val field2: Pair<RequestBody, RequestBody>?, val field2: Pair<String, String>?,
val field3: Pair<RequestBody, RequestBody>?, val field3: Pair<String, String>?,
val field4: Pair<RequestBody, RequestBody>?, val field4: Pair<String, String>?,
val header: MultipartBody.Part?, val headerFile: File?,
val avatar: MultipartBody.Part? val avatarFile: File?
) { ) {
fun hasNoChanges() = displayName == null && note == null && locked == null && fun hasChanges() = displayName != null || note != null || locked != null ||
avatar == null && header == null && field1 == null && field2 == null && avatarFile != null || headerFile != null || field1 != null || field2 != null ||
field3 == null && field4 == null field3 != null || field4 != null
} }
} }