Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Infomaniak Mail - Android
* Copyright (C) 2026 Infomaniak Network SA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.infomaniak.mail.data.api

import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerializationException
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.intOrNull

object IntOrStringSerializer : KSerializer<String> {

override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("IntOrString", PrimitiveKind.STRING)

override fun deserialize(decoder: Decoder): String {
return if (decoder is JsonDecoder) {
val jsonPrimitive = decoder.decodeJsonElement() as? JsonPrimitive
?: throw SerializationException("Expected a primitive element for id")
if (jsonPrimitive.isString) {
jsonPrimitive.content
} else {
jsonPrimitive.intOrNull?.toString() ?: jsonPrimitive.content
}
} else {
decoder.decodeString()
}
}

override fun serialize(encoder: Encoder, value: String) {
encoder.encodeString(value)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package com.infomaniak.mail.data.models.correspondent

import com.infomaniak.mail.data.api.IntOrStringSerializer
import io.realm.kotlin.ext.realmListOf
import io.realm.kotlin.serializers.RealmListKSerializer
import io.realm.kotlin.types.RealmList
Expand All @@ -28,6 +29,8 @@ import kotlinx.serialization.UseSerializers

@Serializable
data class Contact(
@Serializable(with = IntOrStringSerializer::class)
val id: String? = null,
val name: String = "",
val emails: RealmList<String> = realmListOf(),
val avatar: String? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class MergedContact() : RealmObject, Correspondent, ContactAutocompletable {
var comesFromApi: Boolean = false // In opposition to coming from the phone's address book
private set

var remoteContactId: String? = null
private set

var remoteContactGroupIds: RealmList<Int> = realmListOf()

var addressbookIds: RealmList<Int?> = realmListOf()
Expand Down Expand Up @@ -78,6 +81,7 @@ class MergedContact() : RealmObject, Correspondent, ContactAutocompletable {

this.contactedTimes = apiContact.contactedTimes?.get(email)
this.other = apiContact.other
this.remoteContactId = apiContact.id

this.comesFromApi = comesFromApi

Expand Down Expand Up @@ -113,6 +117,7 @@ class MergedContact() : RealmObject, Correspondent, ContactAutocompletable {
avatar = apiContact.avatar
comesFromApi = true
}
remoteContactId = apiContact.id
addressbookIds += realmListOf(apiContact.addressbookId)
remoteContactGroupIds += apiContact.remoteContactGroupIds
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ object RealmDatabase {
private object RealmConfig {

//region Configurations versions
const val USER_INFO_SCHEMA_VERSION = 5L
const val USER_INFO_SCHEMA_VERSION = 6L
const val MAILBOX_INFO_SCHEMA_VERSION = 19L
const val MAILBOX_CONTENT_SCHEMA_VERSION = 37L
//endregion
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/com/infomaniak/mail/ui/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,11 @@ class MainViewModel @Inject constructor(

//region Merged Contacts
val mergedContactsLive: LiveData<MergedContactDictionary> = avatarMergedContactData.mergedContactLiveData

fun shouldShowAddToContacts(recipient: Recipient): Boolean {
val remoteContactId = mergedContactController.getMergedContactFromEmail(recipient.email)?.remoteContactId
return remoteContactId.isNullOrBlank()
}
Comment on lines +311 to +314

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS does not work that way

//endregion

//region Share Thread URL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class DetailedContactBottomSheetDialog : ActionsBottomSheetDialog() {
val bimi = navigationArgs.bimi
containerInfoCertified.isVisible = bimi?.isCertified == true
contactDetails.setCorrespondent(navigationArgs.recipient, bimi)
addToContacts.isVisible = mainViewModel.shouldShowAddToContacts(navigationArgs.recipient)

setupListeners()

Expand Down
Loading