mirror of
https://github.com/bitfireAT/davx5-ose
synced 2024-09-16 00:58:27 +00:00
Show all detected email addresses as account name suggestion
This commit is contained in:
parent
b59f6c8b7e
commit
558ced82da
|
@ -124,6 +124,16 @@ class DavResourceFinderTest {
|
|||
assertNull(finder.getCurrentUserPrincipal(server.url(PATH_CARDDAV), DavResourceFinder.Service.CALDAV))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testQueryEmailAddress() {
|
||||
var info = ServiceInfo()
|
||||
assertArrayEquals(
|
||||
arrayOf("email1@example.com", "email2@example.com"),
|
||||
finder.queryEmailAddress(server.url(PATH_CALDAV + SUBPATH_PRINCIPAL)).toTypedArray()
|
||||
)
|
||||
assertTrue(finder.queryEmailAddress(server.url(PATH_CARDDAV + SUBPATH_PRINCIPAL)).isEmpty())
|
||||
}
|
||||
|
||||
|
||||
// mock server
|
||||
|
||||
|
@ -167,12 +177,19 @@ class DavResourceFinderTest {
|
|||
" <CARD:addressbook/>" +
|
||||
"</resourcetype>"
|
||||
|
||||
PATH_CALDAV + SUBPATH_PRINCIPAL ->
|
||||
props = "<CAL:calendar-user-address-set>" +
|
||||
" <href>urn:unknown-entry</href>" +
|
||||
" <href>mailto:email1@example.com</href>" +
|
||||
" <href>mailto:email2@example.com</href>" +
|
||||
"</CAL:calendar-user-address-set>"
|
||||
|
||||
else -> props = null
|
||||
}
|
||||
Logger.log.info("Sending props: $props")
|
||||
return MockResponse()
|
||||
.setResponseCode(207)
|
||||
.setBody("<multistatus xmlns='DAV:' xmlns:CARD='urn:ietf:params:xml:ns:carddav'>" +
|
||||
.setBody("<multistatus xmlns='DAV:' xmlns:CARD='urn:ietf:params:xml:ns:carddav' xmlns:CAL='urn:ietf:params:xml:ns:caldav'>" +
|
||||
"<response>" +
|
||||
" <href>${request.path}</href>" +
|
||||
" <propstat><prop>$props</prop></propstat>" +
|
||||
|
|
|
@ -18,6 +18,7 @@ import android.provider.CalendarContract
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.*
|
||||
import at.bitfire.davdroid.Constants
|
||||
|
@ -59,9 +60,11 @@ class AccountDetailsFragment: Fragment() {
|
|||
|
||||
val config = loginModel.configuration ?: throw IllegalStateException()
|
||||
|
||||
model.name.value = config.calDAV?.email ?:
|
||||
loginModel.credentials?.userName ?:
|
||||
loginModel.credentials?.certificateAlias
|
||||
// default account name
|
||||
model.name.value =
|
||||
config.calDAV?.emails?.firstOrNull() ?:
|
||||
loginModel.credentials?.userName ?:
|
||||
loginModel.credentials?.certificateAlias
|
||||
|
||||
// CardDAV-specific
|
||||
val settings = Settings.getInstance(requireActivity())
|
||||
|
@ -69,6 +72,12 @@ class AccountDetailsFragment: Fragment() {
|
|||
if (settings.has(AccountSettings.KEY_CONTACT_GROUP_METHOD))
|
||||
v.contactGroupMethod.isEnabled = false
|
||||
|
||||
// CalDAV-specific
|
||||
config.calDAV?.let {
|
||||
val accountNameAdapter = ArrayAdapter<String>(requireActivity(), android.R.layout.simple_list_item_1, it.emails)
|
||||
v.accountName.setAdapter(accountNameAdapter)
|
||||
}
|
||||
|
||||
v.createAccount.setOnClickListener {
|
||||
val name = model.name.value
|
||||
if (name.isNullOrBlank())
|
||||
|
|
|
@ -143,24 +143,10 @@ class DavResourceFinder(
|
|||
}
|
||||
}
|
||||
|
||||
if (config.principal != null && service == Service.CALDAV)
|
||||
// query email address (CalDAV scheduling: calendar-user-address-set)
|
||||
try {
|
||||
DavResource(httpClient.okHttpClient, config.principal!!, log).propfind(0, CalendarUserAddressSet.NAME) { response, _ ->
|
||||
response[CalendarUserAddressSet::class.java]?.let { addressSet ->
|
||||
for (href in addressSet.hrefs)
|
||||
try {
|
||||
val uri = URI(href)
|
||||
if (uri.scheme.equals("mailto", true))
|
||||
config.email = uri.schemeSpecificPart
|
||||
} catch(e: URISyntaxException) {
|
||||
log.log(Level.WARNING, "Couldn't parse user address", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(e: Exception) {
|
||||
log.log(Level.WARNING, "Couldn't query user email address", e)
|
||||
rethrowIfInterrupted(e)
|
||||
// detect email address
|
||||
if (service == Service.CALDAV)
|
||||
config.principal?.let {
|
||||
config.emails.addAll(queryEmailAddress(it))
|
||||
}
|
||||
|
||||
// return config or null if config doesn't contain useful information
|
||||
|
@ -202,6 +188,33 @@ class DavResourceFinder(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries a user's email address using CalDAV scheduling: calendar-user-address-set.
|
||||
* @param principal principal URL of the user
|
||||
* @return list of found email addresses (empty if none)
|
||||
*/
|
||||
fun queryEmailAddress(principal: HttpUrl): List<String> {
|
||||
var mailboxes = LinkedList<String>()
|
||||
try {
|
||||
DavResource(httpClient.okHttpClient, principal, log).propfind(0, CalendarUserAddressSet.NAME) { response, _ ->
|
||||
response[CalendarUserAddressSet::class.java]?.let { addressSet ->
|
||||
for (href in addressSet.hrefs)
|
||||
try {
|
||||
val uri = URI(href)
|
||||
if (uri.scheme.equals("mailto", true))
|
||||
mailboxes.add(uri.schemeSpecificPart)
|
||||
} catch(e: URISyntaxException) {
|
||||
log.log(Level.WARNING, "Couldn't parse user address", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(e: Exception) {
|
||||
log.log(Level.WARNING, "Couldn't query user email address", e)
|
||||
rethrowIfInterrupted(e)
|
||||
}
|
||||
return mailboxes
|
||||
}
|
||||
|
||||
/**
|
||||
* If [dav] references an address book, an address book home set, and/or a princiapl,
|
||||
* it will added to, config.collections, config.homesets and/or config.principal.
|
||||
|
@ -423,7 +436,7 @@ class DavResourceFinder(
|
|||
val homeSets: MutableSet<HttpUrl> = HashSet(),
|
||||
val collections: MutableMap<HttpUrl, Collection> = HashMap(),
|
||||
|
||||
var email: String? = null
|
||||
val emails: MutableList<String> = LinkedList<String>()
|
||||
)
|
||||
|
||||
override fun toString(): String {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package at.bitfire.davdroid.ui.widget
|
||||
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.TextView
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.databinding.BindingAdapter
|
||||
import androidx.databinding.InverseBindingAdapter
|
||||
|
||||
object BindingAdapters {
|
||||
|
||||
|
@ -23,4 +25,15 @@ object BindingAdapters {
|
|||
textView.text = null
|
||||
}
|
||||
|
||||
|
||||
@BindingAdapter("unfilteredText")
|
||||
@JvmStatic
|
||||
fun setUnfilteredText(view: AutoCompleteTextView, text: String?) {
|
||||
view.setText(text, false)
|
||||
}
|
||||
|
||||
@InverseBindingAdapter(attribute = "unfilteredText", event = "android:textAttrChanged")
|
||||
@JvmStatic
|
||||
fun getUnfilteredText(textView: AutoCompleteTextView) = textView.text.toString()
|
||||
|
||||
}
|
||||
|
|
|
@ -44,13 +44,15 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/login_account_name"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
app:errorEnabled="true"
|
||||
app:error="@{details.nameError}">
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/accountName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@={details.name}"
|
||||
android:inputType="textEmailAddress"/>
|
||||
unfilteredText="@={details.name}"
|
||||
android:inputType="textEmailAddress" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
|
|
Loading…
Reference in a new issue