From 1da0674857269ffc5a743dcb2a8a5776de64e181 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Wed, 14 Feb 2018 17:49:39 +0100 Subject: [PATCH] Add option to select identity when composing a message --- .../apps/abit/ComposeMessageFragment.kt | 81 +++++++++++-------- .../apps/abit/adapter/ContactAdapter.kt | 77 ++++++++++-------- app/src/main/res/layout/contact_row_slim.xml | 47 +++++++++++ .../res/layout/fragment_compose_message.xml | 26 ++++-- app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 6 files changed, 159 insertions(+), 74 deletions(-) create mode 100644 app/src/main/res/layout/contact_row_slim.xml diff --git a/app/src/main/java/ch/dissem/apps/abit/ComposeMessageFragment.kt b/app/src/main/java/ch/dissem/apps/abit/ComposeMessageFragment.kt index 0c00f48..c248aef 100644 --- a/app/src/main/java/ch/dissem/apps/abit/ComposeMessageFragment.kt +++ b/app/src/main/java/ch/dissem/apps/abit/ComposeMessageFragment.kt @@ -101,9 +101,8 @@ class ComposeMessageFragment : Fragment() { parent.inventoryVector?.let { parents.add(it) } } } - } ?: { - throw IllegalStateException("No identity set for ComposeMessageFragment") - }.invoke() + } ?: throw IllegalStateException("No identity set for ComposeMessageFragment") + setHasOptionsMenu(true) } @@ -115,37 +114,50 @@ class ComposeMessageFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - if (broadcast) { - recipient_input.visibility = View.GONE - } else { - val adapter = ContactAdapter(context!!) - recipient_input.setAdapter(adapter) - recipient_input.onItemClickListener = - AdapterView.OnItemClickListener { _, _, pos, _ -> adapter.getItem(pos) } - recipient_input.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onItemSelected( - parent: AdapterView<*>, - view: View, - position: Int, - id: Long - ) { - recipient = adapter.getItem(position) - } - - override fun onNothingSelected(parent: AdapterView<*>) = - Unit // leave current selection + context?.let { ctx -> + val identities = Singleton.getAddressRepository(ctx).getIdentities() + sender_input.adapter = ContactAdapter(ctx, identities, true) + val index = identities.indexOf(Singleton.getIdentity(ctx)) + if (index >= 0) { + sender_input.setSelection(index) } - recipient?.let { recipient_input.setText(it.toString()) } - } - subject_input.setText(subject) - body_input.setText(content) - when { - recipient == null -> recipient_input.requestFocus() - subject.isEmpty() -> subject_input.requestFocus() - else -> { - body_input.requestFocus() - body_input.setSelection(0) + if (broadcast) { + recipient_input.visibility = View.GONE + } else { + val adapter = ContactAdapter( + ctx, + Singleton.getAddressRepository(ctx).getContacts() + ) + recipient_input.setAdapter(adapter) + recipient_input.onItemClickListener = + AdapterView.OnItemClickListener { _, _, pos, _ -> adapter.getItem(pos) } + recipient_input.onItemSelectedListener = + object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>, + view: View, + position: Int, + id: Long + ) { + recipient = adapter.getItem(position) + } + + override fun onNothingSelected(parent: AdapterView<*>) = + Unit // leave current selection + } + recipient?.let { recipient_input.setText(it.toString()) } + } + subject_input.setText(subject) + body_input.setText(content) + + when { + recipient == null -> recipient_input.requestFocus() + subject.isEmpty() -> subject_input.requestFocus() + else -> { + body_input.requestFocus() + body_input.setSelection(0) + } } } } @@ -184,7 +196,7 @@ class ComposeMessageFragment : Fragment() { private fun build(ctx: Context): Plaintext { val builder: Plaintext.Builder if (broadcast) { - builder = Plaintext.Builder(BROADCAST).from(identity) + builder = Plaintext.Builder(BROADCAST) } else { val inputString = recipient_input.text.toString() if (recipient == null || recipient?.toString() != inputString) { @@ -203,9 +215,10 @@ class ComposeMessageFragment : Fragment() { } builder = Plaintext.Builder(MSG) - .from(identity) .to(recipient) } + val sender = sender_input.selectedItem as? ch.dissem.bitmessage.entity.BitmessageAddress + sender?.let { builder.from(it) } if (!Preferences.requestAcknowledgements(ctx)) { builder.preventAck() } diff --git a/app/src/main/java/ch/dissem/apps/abit/adapter/ContactAdapter.kt b/app/src/main/java/ch/dissem/apps/abit/adapter/ContactAdapter.kt index b18c3b9..c32e44d 100644 --- a/app/src/main/java/ch/dissem/apps/abit/adapter/ContactAdapter.kt +++ b/app/src/main/java/ch/dissem/apps/abit/adapter/ContactAdapter.kt @@ -20,25 +20,22 @@ import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.BaseAdapter -import android.widget.Filter -import android.widget.Filterable -import android.widget.ImageView -import android.widget.TextView - -import java.util.ArrayList - +import android.widget.* import ch.dissem.apps.abit.Identicon import ch.dissem.apps.abit.R -import ch.dissem.apps.abit.service.Singleton import ch.dissem.bitmessage.entity.BitmessageAddress +import java.util.* /** * An adapter for contacts. Can be filtered by alias or address. */ -class ContactAdapter(ctx: Context) : BaseAdapter(), Filterable { +class ContactAdapter( + ctx: Context, + private val originalData: List, + private val slim: Boolean = false +) : + BaseAdapter(), Filterable { private val inflater = LayoutInflater.from(ctx) - private val originalData = Singleton.getAddressRepository(ctx).getContacts() private var data: List = originalData override fun getCount() = data.size @@ -49,23 +46,33 @@ class ContactAdapter(ctx: Context) : BaseAdapter(), Filterable { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { val viewHolder = if (convertView == null) { - ViewHolder(inflater.inflate(R.layout.contact_row, parent, false)) + ViewHolder( + inflater.inflate( + if (slim) { + R.layout.contact_row_slim + } else { + R.layout.contact_row + }, + parent, false + ) + ) } else { convertView.tag as ViewHolder } val item = getItem(position) viewHolder.avatar.setImageDrawable(Identicon(item)) viewHolder.name.text = item.toString() - viewHolder.address.text = item.address + viewHolder.address?.text = item.address + return viewHolder.view } override fun getFilter(): Filter = ContactFilter() private inner class ViewHolder(val view: View) { - val avatar = view.findViewById(R.id.avatar)!! - val name = view.findViewById(R.id.name)!! - val address = view.findViewById(R.id.address)!! + val avatar: ImageView = view.findViewById(R.id.avatar) + val name: TextView = view.findViewById(R.id.name) + val address: TextView? = view.findViewById(R.id.address) init { view.tag = this @@ -83,27 +90,29 @@ class ContactAdapter(ctx: Context) : BaseAdapter(), Filterable { val newValues = ArrayList() originalData - .forEach { value -> - value.alias?.toLowerCase()?.let { alias -> - if (alias.startsWith(prefixString)) { - newValues.add(value) - } else { - val words = alias.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + .forEach { value -> + value.alias?.toLowerCase()?.let { alias -> + if (alias.startsWith(prefixString)) { + newValues.add(value) + } else { + val words = + alias.split(" ".toRegex()).dropLastWhile { it.isEmpty() } + .toTypedArray() - for (word in words) { - if (word.startsWith(prefixString)) { - newValues.add(value) - break - } + for (word in words) { + if (word.startsWith(prefixString)) { + newValues.add(value) + break } } - } ?: { - val address = value.address.toLowerCase() - if (address.contains(prefixString)) { - newValues.add(value) - } - }.invoke() - } + } + } ?: { + val address = value.address.toLowerCase() + if (address.contains(prefixString)) { + newValues.add(value) + } + }.invoke() + } results.values = newValues results.count = newValues.size diff --git a/app/src/main/res/layout/contact_row_slim.xml b/app/src/main/res/layout/contact_row_slim.xml new file mode 100644 index 0000000..c3308dc --- /dev/null +++ b/app/src/main/res/layout/contact_row_slim.xml @@ -0,0 +1,47 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_compose_message.xml b/app/src/main/res/layout/fragment_compose_message.xml index affc95b..e6a86ba 100644 --- a/app/src/main/res/layout/fragment_compose_message.xml +++ b/app/src/main/res/layout/fragment_compose_message.xml @@ -1,8 +1,22 @@ + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + + + + android:maxLines="1" /> @@ -29,7 +43,7 @@ android:layout_height="wrap_content" android:hint="@string/subject" android:inputType="textEmailSubject" - android:textAppearance="?android:attr/textAppearanceLarge"/> + android:textAppearance="?android:attr/textAppearanceLarge" /> @@ -41,6 +55,6 @@ android:gravity="start|top" android:hint="@string/compose_body_hint" android:inputType="textMultiLine|textCapSentences" - android:scrollbars="vertical"/> + android:scrollbars="vertical" /> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1b7d37c..4a9cc7e 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -127,4 +127,5 @@ Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfigu Import Nachrichten und Kontakte importieren (aber keine Identitäten) Kodierung auswählen + Von diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f5a32c5..9d4edbb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -126,4 +126,5 @@ As an alternative you could configure a trusted node in the settings, but as of Acknowledges allow making sure a message was received, but require additional time to send Got it Select encoding + From