From f481914a65d513d8526ffcbffc430cad8eb233b9 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Tue, 13 Feb 2018 07:24:24 +0100 Subject: [PATCH 1/5] Implemented basic draft functionality --- .../apps/abit/ComposeMessageActivity.kt | 1 + .../apps/abit/ComposeMessageFragment.kt | 165 ++++++++++++------ .../java/ch/dissem/apps/abit/MainActivity.kt | 136 ++++++++++----- build.gradle | 2 +- 4 files changed, 201 insertions(+), 103 deletions(-) diff --git a/app/src/main/java/ch/dissem/apps/abit/ComposeMessageActivity.kt b/app/src/main/java/ch/dissem/apps/abit/ComposeMessageActivity.kt index dcea268..618504a 100644 --- a/app/src/main/java/ch/dissem/apps/abit/ComposeMessageActivity.kt +++ b/app/src/main/java/ch/dissem/apps/abit/ComposeMessageActivity.kt @@ -53,6 +53,7 @@ class ComposeMessageActivity : AppCompatActivity() { } companion object { + const val EXTRA_DRAFT = "ch.dissem.abit.Message.DRAFT" const val EXTRA_IDENTITY = "ch.dissem.abit.Message.SENDER" const val EXTRA_RECIPIENT = "ch.dissem.abit.Message.RECIPIENT" const val EXTRA_SUBJECT = "ch.dissem.abit.Message.SUBJECT" 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 75755ba..0c00f48 100644 --- a/app/src/main/java/ch/dissem/apps/abit/ComposeMessageFragment.kt +++ b/app/src/main/java/ch/dissem/apps/abit/ComposeMessageFragment.kt @@ -17,6 +17,7 @@ package ch.dissem.apps.abit import android.app.Activity.RESULT_OK +import android.content.Context import android.content.Intent import android.os.Bundle import android.support.v4.app.Fragment @@ -25,6 +26,7 @@ import android.widget.AdapterView import android.widget.Toast import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_BROADCAST import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_CONTENT +import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_DRAFT import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_ENCODING import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_IDENTITY import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_PARENT @@ -38,6 +40,9 @@ import ch.dissem.bitmessage.entity.BitmessageAddress import ch.dissem.bitmessage.entity.Plaintext import ch.dissem.bitmessage.entity.Plaintext.Type.BROADCAST import ch.dissem.bitmessage.entity.Plaintext.Type.MSG +import ch.dissem.bitmessage.entity.valueobject.ExtendedEncoding +import ch.dissem.bitmessage.entity.valueobject.InventoryVector +import ch.dissem.bitmessage.entity.valueobject.Label import ch.dissem.bitmessage.entity.valueobject.extended.Message import kotlinx.android.synthetic.main.fragment_compose_message.* @@ -52,34 +57,49 @@ class ComposeMessageFragment : Fragment() { private var broadcast: Boolean = false private var encoding: Plaintext.Encoding = Plaintext.Encoding.SIMPLE - private var parent: Plaintext? = null + private val parents = mutableListOf() + + private var draft: Plaintext? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - arguments?.let { arguments -> - var id = arguments.getSerializable(EXTRA_IDENTITY) as? BitmessageAddress - if (context != null && (id == null || id.privateKey == null)) { - id = Singleton.getIdentity(context!!) - } - if (id?.privateKey != null) { - identity = id + arguments?.apply { + val draft = getSerializable(EXTRA_DRAFT) as Plaintext? + if (draft != null) { + this@ComposeMessageFragment.draft = draft + identity = draft.from + recipient = draft.to + subject = draft.subject ?: "" + content = draft.text ?: "" + encoding = draft.encoding ?: Plaintext.Encoding.SIMPLE + parents.addAll(draft.parents) } else { - throw IllegalStateException("No identity set for ComposeMessageFragment") - } - broadcast = arguments.getBoolean(EXTRA_BROADCAST, false) - if (arguments.containsKey(EXTRA_RECIPIENT)) { - recipient = arguments.getSerializable(EXTRA_RECIPIENT) as BitmessageAddress - } - if (arguments.containsKey(EXTRA_SUBJECT)) { - subject = arguments.getString(EXTRA_SUBJECT) - } - if (arguments.containsKey(EXTRA_CONTENT)) { - content = arguments.getString(EXTRA_CONTENT) - } - encoding = arguments.getSerializable(EXTRA_ENCODING) as? Plaintext.Encoding ?: Plaintext.Encoding.SIMPLE + var id = getSerializable(EXTRA_IDENTITY) as? BitmessageAddress + if (context != null && (id == null || id.privateKey == null)) { + id = Singleton.getIdentity(context!!) + } + if (id?.privateKey != null) { + identity = id + } else { + throw IllegalStateException("No identity set for ComposeMessageFragment") + } + broadcast = getBoolean(EXTRA_BROADCAST, false) + if (containsKey(EXTRA_RECIPIENT)) { + recipient = getSerializable(EXTRA_RECIPIENT) as BitmessageAddress + } + if (containsKey(EXTRA_SUBJECT)) { + subject = getString(EXTRA_SUBJECT) + } + if (containsKey(EXTRA_CONTENT)) { + content = getString(EXTRA_CONTENT) + } + encoding = getSerializable(EXTRA_ENCODING) as? Plaintext.Encoding ?: + Plaintext.Encoding.SIMPLE - if (arguments.containsKey(EXTRA_PARENT)) { - parent = arguments.getSerializable(EXTRA_PARENT) as Plaintext + if (containsKey(EXTRA_PARENT)) { + val parent = getSerializable(EXTRA_PARENT) as Plaintext + parent.inventoryVector?.let { parents.add(it) } + } } } ?: { throw IllegalStateException("No identity set for ComposeMessageFragment") @@ -87,9 +107,10 @@ class ComposeMessageFragment : Fragment() { setHasOptionsMenu(true) } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View = - inflater.inflate(R.layout.fragment_compose_message, container, false) + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View = inflater.inflate(R.layout.fragment_compose_message, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -99,13 +120,20 @@ class ComposeMessageFragment : Fragment() { } else { val adapter = ContactAdapter(context!!) recipient_input.setAdapter(adapter) - recipient_input.onItemClickListener = AdapterView.OnItemClickListener { _, _, pos, _ -> adapter.getItem(pos) } + 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) { + override fun onItemSelected( + parent: AdapterView<*>, + view: View, + position: Int, + id: Long + ) { recipient = adapter.getItem(position) } - override fun onNothingSelected(parent: AdapterView<*>) = Unit // leave current selection + override fun onNothingSelected(parent: AdapterView<*>) = + Unit // leave current selection } recipient?.let { recipient_input.setText(it.toString()) } } @@ -146,16 +174,15 @@ class ComposeMessageFragment : Fragment() { } } - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) = if (requestCode == 0 && data != null && resultCode == RESULT_OK) { - encoding = data.getSerializableExtra(EXTRA_ENCODING) as Plaintext.Encoding - } else { - super.onActivityResult(requestCode, resultCode, data) - } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) = + if (requestCode == 0 && data != null && resultCode == RESULT_OK) { + encoding = data.getSerializableExtra(EXTRA_ENCODING) as Plaintext.Encoding + } else { + super.onActivityResult(requestCode, resultCode, data) + } - private fun send() { + private fun build(ctx: Context): Plaintext { val builder: Plaintext.Builder - val ctx = activity ?: throw IllegalStateException("Fragment is not attached to an activity") - val bmc = Singleton.getBitmessageContext(ctx) if (broadcast) { builder = Plaintext.Builder(BROADCAST).from(identity) } else { @@ -175,42 +202,68 @@ class ComposeMessageFragment : Fragment() { } } - if (recipient == null) { - Toast.makeText(context, R.string.error_msg_recipient_missing, Toast.LENGTH_LONG).show() - return - } builder = Plaintext.Builder(MSG) - .from(identity) - .to(recipient) + .from(identity) + .to(recipient) } if (!Preferences.requestAcknowledgements(ctx)) { builder.preventAck() } when (encoding) { Plaintext.Encoding.SIMPLE -> builder.message( - subject_input.text.toString(), - body_input.text.toString() + subject_input.text.toString(), + body_input.text.toString() ) Plaintext.Encoding.EXTENDED -> builder.message( - Message.Builder() - .subject(subject_input.text.toString()) - .body(body_input.text.toString()) - .addParent(parent) - .build() + ExtendedEncoding( + Message( + subject = subject_input.text.toString(), + body = body_input.text.toString(), + parents = parents, + files = emptyList() + ) + ) ) else -> { Toast.makeText( - ctx, - ctx.getString(R.string.error_unsupported_encoding, encoding), - Toast.LENGTH_LONG + ctx, + ctx.getString(R.string.error_unsupported_encoding, encoding), + Toast.LENGTH_LONG ).show() builder.message( - subject_input.text.toString(), - body_input.text.toString() + subject_input.text.toString(), + body_input.text.toString() ) } } - bmc.send(builder.build()) + draft?.id?.let { builder.id(it) } + return builder.build() + } + + override fun onPause() { + if (draft?.labels?.any { it.type == Label.Type.DRAFT } != false) { + context?.let { ctx -> + draft = build(ctx).also { msg -> + Singleton.labeler.markAsDraft(msg) + Singleton.getMessageRepository(ctx).save(msg) + } + Toast.makeText(ctx, "Message saved as draft", Toast.LENGTH_LONG).show() + } ?: throw IllegalStateException("Context is not available") + } + super.onPause() + } + + private fun send() { + val ctx = activity ?: throw IllegalStateException("Fragment is not attached to an activity") + if (recipient == null) { + Toast.makeText(ctx, R.string.error_msg_recipient_missing, Toast.LENGTH_LONG) + .show() + return + } + build(ctx).let { message -> + draft = message + Singleton.getBitmessageContext(ctx).send(message) + } ctx.finish() } } diff --git a/app/src/main/java/ch/dissem/apps/abit/MainActivity.kt b/app/src/main/java/ch/dissem/apps/abit/MainActivity.kt index 2f1d3aa..6c77f0f 100644 --- a/app/src/main/java/ch/dissem/apps/abit/MainActivity.kt +++ b/app/src/main/java/ch/dissem/apps/abit/MainActivity.kt @@ -146,12 +146,15 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { SyncAdapter.stopSync(this) } if (drawer.isDrawerOpen) { - val lps = RelativeLayout.LayoutParams(ViewGroup - .LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) - lps.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM) - lps.addRule(RelativeLayout.ALIGN_PARENT_LEFT) - val margin = ((resources.displayMetrics.density * 12) as Number).toInt() - lps.setMargins(margin, margin, margin, margin) + val lps = RelativeLayout.LayoutParams( + ViewGroup + .LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT + ).apply { + addRule(RelativeLayout.ALIGN_PARENT_BOTTOM) + addRule(RelativeLayout.ALIGN_PARENT_LEFT) + val margin = ((resources.displayMetrics.density * 12) as Number).toInt() + setMargins(margin, margin, margin, margin) + } ShowcaseView.Builder(this) .withMaterialShowcase() @@ -192,19 +195,23 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { private fun createDrawer(toolbar: Toolbar) { val profiles = ArrayList>() - profiles.add(ProfileSettingDrawerItem() - .withName(getString(R.string.add_identity)) - .withDescription(getString(R.string.add_identity_summary)) - .withIcon(IconicsDrawable(this, GoogleMaterial.Icon.gmd_add) - .actionBar() - .paddingDp(5) - .colorRes(R.color.icons)) - .withIdentifier(ADD_IDENTITY.toLong()) + profiles.add( + ProfileSettingDrawerItem() + .withName(getString(R.string.add_identity)) + .withDescription(getString(R.string.add_identity_summary)) + .withIcon( + IconicsDrawable(this, GoogleMaterial.Icon.gmd_add) + .actionBar() + .paddingDp(5) + .colorRes(R.color.icons) + ) + .withIdentifier(ADD_IDENTITY.toLong()) ) - profiles.add(ProfileSettingDrawerItem() - .withName(getString(R.string.manage_identity)) - .withIcon(GoogleMaterial.Icon.gmd_settings) - .withIdentifier(MANAGE_IDENTITY.toLong()) + profiles.add( + ProfileSettingDrawerItem() + .withName(getString(R.string.manage_identity)) + .withIcon(GoogleMaterial.Icon.gmd_settings) + .withIdentifier(MANAGE_IDENTITY.toLong()) ) // Create the AccountHeader accountHeader = AccountHeaderBuilder() @@ -212,26 +219,36 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { .withHeaderBackground(R.drawable.header) .withProfiles(profiles) .withOnAccountHeaderProfileImageListener(ProfileImageListener(this)) - .withOnAccountHeaderListener(ProfileSelectionListener(this@MainActivity, supportFragmentManager)) + .withOnAccountHeaderListener( + ProfileSelectionListener( + this@MainActivity, + supportFragmentManager + ) + ) .build() if (profiles.size > 2) { // There's always the add and manage identity items accountHeader.setActiveProfile(profiles[0], true) } val drawerItems = ArrayList>() - drawerItems.add(PrimaryDrawerItem() - .withIdentifier(LABEL_ARCHIVE.id as Long) - .withName(R.string.archive) - .withTag(LABEL_ARCHIVE) - .withIcon(CommunityMaterial.Icon.cmd_archive) + drawerItems.add( + PrimaryDrawerItem() + .withIdentifier(LABEL_ARCHIVE.id as Long) + .withName(R.string.archive) + .withTag(LABEL_ARCHIVE) + .withIcon(CommunityMaterial.Icon.cmd_archive) ) drawerItems.add(DividerDrawerItem()) - drawerItems.add(PrimaryDrawerItem() - .withName(R.string.contacts_and_subscriptions) - .withIcon(GoogleMaterial.Icon.gmd_contacts)) - drawerItems.add(PrimaryDrawerItem() - .withName(R.string.settings) - .withIcon(GoogleMaterial.Icon.gmd_settings)) + drawerItems.add( + PrimaryDrawerItem() + .withName(R.string.contacts_and_subscriptions) + .withIcon(GoogleMaterial.Icon.gmd_contacts) + ) + drawerItems.add( + PrimaryDrawerItem() + .withName(R.string.settings) + .withIcon(GoogleMaterial.Icon.gmd_settings) + ) nodeSwitch = SwitchDrawerItem() .withIdentifier(ID_NODE_SWITCH) @@ -369,7 +386,8 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { // we know that there are 2 setting elements. // Set the new profile above them ;) accountHeader.addProfile( - newProfile, accountHeader.profiles.size - 2) + newProfile, accountHeader.profiles.size - 2 + ) } else { accountHeader.addProfiles(newProfile) } @@ -435,14 +453,31 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { // In two-pane mode, show the detail view in this activity by // adding or replacing the detail fragment using a // fragment transaction. - val arguments = Bundle() - arguments.putSerializable(MessageDetailFragment.ARG_ITEM, item) val fragment = when (item) { - is Plaintext -> MessageDetailFragment() - is BitmessageAddress -> AddressDetailFragment() + is Plaintext -> { + if (item.labels.any { it.type == Label.Type.DRAFT }) { + ComposeMessageFragment().apply { + arguments = Bundle().apply { + putSerializable(ComposeMessageActivity.EXTRA_DRAFT, item) + } + } + } else { + MessageDetailFragment().apply { + arguments = Bundle().apply { + putSerializable(MessageDetailFragment.ARG_ITEM, item) + } + } + } + } + is BitmessageAddress -> { + AddressDetailFragment().apply { + arguments = Bundle().apply { + putSerializable(AddressDetailFragment.ARG_ITEM, item) + } + } + } else -> throw IllegalArgumentException("Plaintext or BitmessageAddress expected, but was ${item::class.simpleName}") } - fragment.arguments = arguments supportFragmentManager.beginTransaction() .replace(R.id.message_detail_container, fragment) .commit() @@ -451,12 +486,21 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { // for the selected item ID. val detailIntent = when (item) { is Plaintext -> { - Intent(this, MessageDetailActivity::class.java) + if (item.labels.any { it.type == Label.Type.DRAFT }) { + Intent(this, ComposeMessageActivity::class.java).apply { + putExtra(ComposeMessageActivity.EXTRA_DRAFT, item) + } + } else { + Intent(this, MessageDetailActivity::class.java).apply { + putExtra(MessageDetailFragment.ARG_ITEM, item) + } + } + } + is BitmessageAddress -> Intent(this, AddressDetailActivity::class.java).apply { + putExtra(AddressDetailFragment.ARG_ITEM, item) } - is BitmessageAddress -> Intent(this, AddressDetailActivity::class.java) else -> throw IllegalArgumentException("Plaintext or BitmessageAddress expected, but was ${item::class.simpleName}") } - detailIntent.putExtra(MessageDetailFragment.ARG_ITEM, item) startActivity(detailIntent) } } @@ -474,15 +518,15 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { } companion object { - val EXTRA_SHOW_MESSAGE = "ch.dissem.abit.ShowMessage" - val EXTRA_SHOW_LABEL = "ch.dissem.abit.ShowLabel" - val EXTRA_REPLY_TO_MESSAGE = "ch.dissem.abit.ReplyToMessage" - val ACTION_SHOW_INBOX = "ch.dissem.abit.ShowInbox" + const val EXTRA_SHOW_MESSAGE = "ch.dissem.abit.ShowMessage" + const val EXTRA_SHOW_LABEL = "ch.dissem.abit.ShowLabel" + const val EXTRA_REPLY_TO_MESSAGE = "ch.dissem.abit.ReplyToMessage" + const val ACTION_SHOW_INBOX = "ch.dissem.abit.ShowInbox" - val ADD_IDENTITY = 1 - val MANAGE_IDENTITY = 2 + const val ADD_IDENTITY = 1 + const val MANAGE_IDENTITY = 2 - private val ID_NODE_SWITCH: Long = 1 + private const val ID_NODE_SWITCH: Long = 1 private var instance: WeakReference? = null diff --git a/build.gradle b/build.gradle index 1a6c091..9232626 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.2.20' + ext.kotlin_version = '1.2.21' ext.anko_version = '0.10.4' repositories { jcenter() From 1da0674857269ffc5a743dcb2a8a5776de64e181 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Wed, 14 Feb 2018 17:49:39 +0100 Subject: [PATCH 2/5] 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 From 39ad5e8bafdbc31200b43fe8eafc6902f04b8a5d Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Mon, 19 Feb 2018 23:38:40 +0100 Subject: [PATCH 3/5] Improve scrolling behaviour for the compose view --- .../res/layout/fragment_compose_message.xml | 114 ++++++++++-------- 1 file changed, 61 insertions(+), 53 deletions(-) diff --git a/app/src/main/res/layout/fragment_compose_message.xml b/app/src/main/res/layout/fragment_compose_message.xml index e6a86ba..afdbd77 100644 --- a/app/src/main/res/layout/fragment_compose_message.xml +++ b/app/src/main/res/layout/fragment_compose_message.xml @@ -1,60 +1,68 @@ - + android:fillViewport="true"> - - - - - - - - - - - - - - - - - + android:orientation="vertical"> - + + + + + + + + + + + + + + + + + + + + From 21abdbd7201f527c8bd93e112ac6d693f0da936c Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Mon, 19 Feb 2018 23:55:48 +0100 Subject: [PATCH 4/5] Add link to detail view of the sender --- .../dissem/apps/abit/MessageDetailFragment.kt | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/ch/dissem/apps/abit/MessageDetailFragment.kt b/app/src/main/java/ch/dissem/apps/abit/MessageDetailFragment.kt index ff630b3..44f73b3 100644 --- a/app/src/main/java/ch/dissem/apps/abit/MessageDetailFragment.kt +++ b/app/src/main/java/ch/dissem/apps/abit/MessageDetailFragment.kt @@ -70,7 +70,11 @@ class MessageDetailFragment : Fragment() { setHasOptionsMenu(true) } - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View = inflater.inflate(R.layout.fragment_message_detail, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -84,6 +88,13 @@ class MessageDetailFragment : Fragment() { status.setImageResource(Assets.getStatusDrawable(item.status)) status.contentDescription = getString(Assets.getStatusString(item.status)) avatar.setImageDrawable(Identicon(item.from)) + val senderClickListener: (View) -> Unit = { + MainActivity.apply { + onItemSelected(item.from) + } + } + avatar.setOnClickListener(senderClickListener) + sender.setOnClickListener(senderClickListener) sender.text = item.from.toString() item.to?.let { to -> recipient.text = to.toString() @@ -124,7 +135,11 @@ class MessageDetailFragment : Fragment() { } } - private fun showRelatedMessages(ctx: Context, rootView: View, @IdRes id: Int, messages: List) { + private fun showRelatedMessages( + ctx: Context, + rootView: View, @IdRes id: Int, + messages: List<Plaintext> + ) { val recyclerView = rootView.findViewById<RecyclerView>(id) val adapter = RelatedMessageAdapter(ctx, messages) recyclerView.adapter = adapter @@ -136,8 +151,10 @@ class MessageDetailFragment : Fragment() { activity?.let { activity -> Drawables.addIcon(activity, menu, R.id.reply, GoogleMaterial.Icon.gmd_reply) Drawables.addIcon(activity, menu, R.id.delete, GoogleMaterial.Icon.gmd_delete) - Drawables.addIcon(activity, menu, R.id.mark_unread, GoogleMaterial.Icon - .gmd_markunread) + Drawables.addIcon( + activity, menu, R.id.mark_unread, GoogleMaterial.Icon + .gmd_markunread + ) Drawables.addIcon(activity, menu, R.id.archive, GoogleMaterial.Icon.gmd_archive) } @@ -187,9 +204,15 @@ class MessageDetailFragment : Fragment() { return false } - private class RelatedMessageAdapter internal constructor(private val ctx: Context, private val messages: List<Plaintext>) : RecyclerView.Adapter<RelatedMessageAdapter.ViewHolder>() { + private class RelatedMessageAdapter internal constructor( + private val ctx: Context, + private val messages: List<Plaintext> + ) : RecyclerView.Adapter<RelatedMessageAdapter.ViewHolder>() { - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RelatedMessageAdapter.ViewHolder { + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): RelatedMessageAdapter.ViewHolder { val context = parent.context val inflater = LayoutInflater.from(context) @@ -236,7 +259,8 @@ class MessageDetailFragment : Fragment() { } } - private class LabelAdapter internal constructor(private val ctx: Context, labels: Set<Label>) : RecyclerView.Adapter<LabelAdapter.ViewHolder>() { + private class LabelAdapter internal constructor(private val ctx: Context, labels: Set<Label>) : + RecyclerView.Adapter<LabelAdapter.ViewHolder>() { private val labels = labels.toMutableList() From 9eefbad7d6b39378b0271eb3b9a76705c5105d17 Mon Sep 17 00:00:00 2001 From: Christian Basler <chrigu.meyer@gmail.com> Date: Tue, 20 Feb 2018 16:40:03 +0100 Subject: [PATCH 5/5] Fix lint issues --- app/build.gradle | 3 +- app/src/main/AndroidManifest.xml | 124 ++++++++++-------- .../dissem/apps/abit/AddressDetailFragment.kt | 4 +- .../java/ch/dissem/apps/abit/Identicon.kt | 4 +- .../apps/abit/ImportIdentitiesFragment.kt | 2 +- .../java/ch/dissem/apps/abit/ListHolder.kt | 2 +- .../java/ch/dissem/apps/abit/MainActivity.kt | 3 +- .../dissem/apps/abit/MessageDetailFragment.kt | 2 +- .../abit/notification/ErrorNotification.kt | 2 +- .../notification/NewMessageNotification.kt | 2 +- .../apps/abit/repository/AndroidInventory.kt | 4 +- .../AndroidProofOfWorkRepository.kt | 16 +-- .../dissem/apps/abit/repository/SqlHelper.kt | 4 +- .../apps/abit/service/BitmessageService.kt | 2 - .../apps/abit/service/ProofOfWorkService.kt | 1 - .../abit/service/StartupNodeOnWifiService.kt | 1 - .../apps/abit/synchronization/SyncService.kt | 1 - .../ch/dissem/apps/abit/util/Drawables.kt | 2 +- .../ch/dissem/apps/abit/util/Observable.kt | 2 +- .../ch/dissem/apps/abit/util/PRNGFixes.java | 60 ++++----- app/src/main/res/layout/contact_row.xml | 4 +- .../dialog_add_deterministic_identity.xml | 23 ++-- app/src/main/res/layout/message_row.xml | 1 + .../main/res/layout/select_identity_row.xml | 18 +-- app/src/main/res/values/styles.xml | 2 +- app/src/main/res/xml/file_paths.xml | 2 +- app/src/main/res/xml/preferences.xml | 56 ++++---- .../AndroidAddressRepositoryTest.kt | 4 +- .../repository/AndroidInventoryTest.kt | 15 ++- .../repository/AndroidLabelRepositoryTest.kt | 3 +- .../AndroidMessageRepositoryTest.kt | 5 +- .../repository/AndroidNodeRegistryTest.kt | 4 +- .../AndroidProofOfWorkRepositoryTest.kt | 2 +- 33 files changed, 191 insertions(+), 189 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 97321b4..4495a2c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -62,7 +62,8 @@ dependencies { implementation "com.android.support:appcompat-v7:$supportVersion" implementation "com.android.support:preference-v7:$supportVersion" implementation "com.android.support:cardview-v7:$supportVersion" - implementation "com.android.support:support-v4:$supportVersion" + implementation "com.android.support:support-v13:$supportVersion" + implementation "com.android.support:preference-v14:$supportVersion" implementation "com.android.support:design:$supportVersion" implementation "com.android.support:multidex:1.0.2" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ddca7b0..cc7f881 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,32 +1,32 @@ <?xml version="1.0" encoding="utf-8"?> -<manifest - package="ch.dissem.apps.abit" - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools"> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="ch.dissem.apps.abit"> - <uses-permission android:name="android.permission.INTERNET"/> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> - <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/> - <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/> - <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/> - <uses-permission android:name="android.permission.READ_CONTACTS"/> - <uses-permission android:name="android.permission.WRITE_CONTACTS"/> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> + <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" /> + <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" /> + <uses-permission android:name="android.permission.READ_CONTACTS" /> + <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <application + android:name="android.support.multidex.MultiDexApplication" android:allowBackup="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" - android:theme="@style/AppTheme" - android:name="android.support.multidex.MultiDexApplication"> + android:supportsRtl="true" + android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> - <action android:name="android.intent.action.MAIN"/> + <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER"/> + <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity @@ -36,7 +36,7 @@ tools:ignore="UnusedAttribute"> <meta-data android:name="android.support.PARENT_ACTIVITY" - android:value=".MainActivity"/> + android:value=".MainActivity" /> </activity> <activity android:name=".AddressDetailActivity" @@ -45,42 +45,42 @@ tools:ignore="UnusedAttribute"> <meta-data android:name="android.support.PARENT_ACTIVITY" - android:value=".MainActivity"/> + android:value=".MainActivity" /> </activity> <activity android:name=".dialog.FullNodeDialogActivity" android:label="@string/full_node" - android:theme="@style/Theme.AppCompat.Light.Dialog"/> + android:theme="@style/Theme.AppCompat.Light.Dialog" /> <activity android:name=".ComposeMessageActivity" android:label="@string/compose_message" android:parentActivityName=".MainActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" - android:value=".MainActivity"/> + android:value=".MainActivity" /> <intent-filter> - <action android:name="android.intent.action.SENDTO"/> + <action android:name="android.intent.action.SENDTO" /> - <data android:scheme="bitmessage"/> - <data android:scheme="bitmsg"/> - <data android:scheme="bm"/> + <data android:scheme="bitmessage" /> + <data android:scheme="bitmsg" /> + <data android:scheme="bm" /> - <category android:name="android.intent.category.DEFAULT"/> + <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> - <action android:name="android.intent.action.SEND"/> + <action android:name="android.intent.action.SEND" /> - <data android:mimeType="text/plain"/> + <data android:mimeType="text/plain" /> - <category android:name="android.intent.category.DEFAULT"/> + <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> - <action android:name="android.intent.action.SEND_MULTIPLE"/> + <action android:name="android.intent.action.SEND_MULTIPLE" /> - <data android:mimeType="text/plain"/> + <data android:mimeType="text/plain" /> - <category android:name="android.intent.category.DEFAULT"/> + <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <activity @@ -88,14 +88,14 @@ android:label="@string/title_activity_open_bitmessage_link" android:theme="@style/Theme.AppCompat.Light.Dialog"> <intent-filter> - <action android:name="android.intent.action.VIEW"/> + <action android:name="android.intent.action.VIEW" /> - <data android:scheme="bitmessage"/> - <data android:scheme="bitmsg"/> - <data android:scheme="bm"/> + <data android:scheme="bitmessage" /> + <data android:scheme="bitmsg" /> + <data android:scheme="bm" /> - <category android:name="android.intent.category.DEFAULT"/> - <category android:name="android.intent.category.BROWSABLE"/> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> </intent-filter> </activity> <activity @@ -104,34 +104,34 @@ android:parentActivityName=".MainActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" - android:value=".MainActivity"/> + android:value=".MainActivity" /> <intent-filter> - <action android:name="android.intent.action.VIEW"/> + <action android:name="android.intent.action.VIEW" /> <data android:host="*" android:mimeType="*/*" android:pathPattern=".*\\.dat" - android:scheme="file"/> + android:scheme="file" /> - <category android:name="android.intent.category.DEFAULT"/> - <category android:name="android.intent.category.BROWSABLE"/> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> </intent-filter> </activity> <service android:name=".service.BitmessageService" - android:exported="false"/> + android:exported="false" /> <service android:name=".service.ProofOfWorkService" - android:exported="false"/> + android:exported="false" /> <!-- Synchronization --> <provider android:name=".synchronization.StubProvider" android:authorities="ch.dissem.apps.abit.provider" android:exported="false" - android:syncable="true"/> + android:syncable="true" /> <!-- Exports --> <provider @@ -149,44 +149,54 @@ android:exported="true" tools:ignore="ExportedService"> <intent-filter> - <action android:name="android.accounts.AccountAuthenticator"/> + <action android:name="android.accounts.AccountAuthenticator" /> </intent-filter> <meta-data android:name="android.accounts.AccountAuthenticator" - android:resource="@xml/authenticator"/> + android:resource="@xml/authenticator" /> </service> <service android:name=".synchronization.SyncService" android:exported="true" tools:ignore="ExportedService"> <intent-filter> - <action android:name="android.content.SyncAdapter"/> + <action android:name="android.content.SyncAdapter" /> </intent-filter> <meta-data android:name="android.content.SyncAdapter" - android:resource="@xml/syncadapter"/> + android:resource="@xml/syncadapter" /> </service> <service android:name=".service.BitmessageIntentService" - android:exported="false"/> + android:exported="false" /> <!-- Receive Wi-Fi connection state changes --> - <receiver android:name=".listener.WifiReceiver" android:enabled="@bool/is_pre_api_21"> + <receiver + android:name=".listener.WifiReceiver" + android:enabled="@bool/is_pre_api_21"> <intent-filter> - <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> + <!-- This is bad for battery life, but needed on older devices to check + if WiFi is available. Let's be honest, the whole app is bad for + battery life. --> + <action + android:name="android.net.conn.CONNECTIVITY_CHANGE" + tools:ignore="BatteryLife" /> </intent-filter> </receiver> - <receiver android:name=".service.StartServiceReceiver" android:enabled="@bool/is_post_api_21"> + <receiver + android:name=".service.StartServiceReceiver" + android:enabled="@bool/is_post_api_21"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> + <service android:name=".service.StartupNodeOnWifiService" - android:permission="android.permission.BIND_JOB_SERVICE" - android:exported="true"/> + android:exported="true" + android:permission="android.permission.BIND_JOB_SERVICE" /> <activity android:name=".StatusActivity" @@ -194,7 +204,7 @@ android:parentActivityName=".MainActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" - android:value=".MainActivity"/> + android:value=".MainActivity" /> </activity> </application> diff --git a/app/src/main/java/ch/dissem/apps/abit/AddressDetailFragment.kt b/app/src/main/java/ch/dissem/apps/abit/AddressDetailFragment.kt index 9a4ea03..af66c9e 100644 --- a/app/src/main/java/ch/dissem/apps/abit/AddressDetailFragment.kt +++ b/app/src/main/java/ch/dissem/apps/abit/AddressDetailFragment.kt @@ -204,7 +204,7 @@ class AddressDetailFragment : Fragment() { * The fragment argument representing the item ID that this fragment * represents. */ - val ARG_ITEM = "item" - val EXPORT_POSTFIX = ".keys.dat" + const val ARG_ITEM = "item" + const val EXPORT_POSTFIX = ".keys.dat" } } diff --git a/app/src/main/java/ch/dissem/apps/abit/Identicon.kt b/app/src/main/java/ch/dissem/apps/abit/Identicon.kt index 172c22d..595158f 100644 --- a/app/src/main/java/ch/dissem/apps/abit/Identicon.kt +++ b/app/src/main/java/ch/dissem/apps/abit/Identicon.kt @@ -92,7 +92,7 @@ class Identicon(input: BitmessageAddress) : Drawable() { override fun getOpacity() = PixelFormat.TRANSPARENT companion object { - private val SIZE = 9 - private val CENTER_COLUMN = 5 + private const val SIZE = 9 + private const val CENTER_COLUMN = 5 } } diff --git a/app/src/main/java/ch/dissem/apps/abit/ImportIdentitiesFragment.kt b/app/src/main/java/ch/dissem/apps/abit/ImportIdentitiesFragment.kt index c65b3ed..5cbdf4e 100644 --- a/app/src/main/java/ch/dissem/apps/abit/ImportIdentitiesFragment.kt +++ b/app/src/main/java/ch/dissem/apps/abit/ImportIdentitiesFragment.kt @@ -72,6 +72,6 @@ class ImportIdentitiesFragment : Fragment() { } companion object { - val WIF_DATA = "wif_data" + const val WIF_DATA = "wif_data" } } diff --git a/app/src/main/java/ch/dissem/apps/abit/ListHolder.kt b/app/src/main/java/ch/dissem/apps/abit/ListHolder.kt index a72ad87..ca07057 100644 --- a/app/src/main/java/ch/dissem/apps/abit/ListHolder.kt +++ b/app/src/main/java/ch/dissem/apps/abit/ListHolder.kt @@ -19,7 +19,7 @@ package ch.dissem.apps.abit /** * @author Christian Basler */ -interface ListHolder<L> { +interface ListHolder<in L> { fun updateList(label: L) fun setActivateOnItemClick(activateOnItemClick: Boolean) diff --git a/app/src/main/java/ch/dissem/apps/abit/MainActivity.kt b/app/src/main/java/ch/dissem/apps/abit/MainActivity.kt index 6c77f0f..ae95bde 100644 --- a/app/src/main/java/ch/dissem/apps/abit/MainActivity.kt +++ b/app/src/main/java/ch/dissem/apps/abit/MainActivity.kt @@ -507,7 +507,8 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> { fun setDetailView(fragment: Fragment) { if (hasDetailPane) { - supportFragmentManager.beginTransaction() + supportFragmentManager + .beginTransaction() .replace(R.id.message_detail_container, fragment) .commit() } diff --git a/app/src/main/java/ch/dissem/apps/abit/MessageDetailFragment.kt b/app/src/main/java/ch/dissem/apps/abit/MessageDetailFragment.kt index 44f73b3..6e08ad2 100644 --- a/app/src/main/java/ch/dissem/apps/abit/MessageDetailFragment.kt +++ b/app/src/main/java/ch/dissem/apps/abit/MessageDetailFragment.kt @@ -298,7 +298,7 @@ class MessageDetailFragment : Fragment() { * The fragment argument representing the item ID that this fragment * represents. */ - val ARG_ITEM = "item" + const val ARG_ITEM = "item" fun isInTrash(item: Plaintext?) = item?.labels?.any { it.type == Label.Type.TRASH } == true } diff --git a/app/src/main/java/ch/dissem/apps/abit/notification/ErrorNotification.kt b/app/src/main/java/ch/dissem/apps/abit/notification/ErrorNotification.kt index 052c638..749fe71 100644 --- a/app/src/main/java/ch/dissem/apps/abit/notification/ErrorNotification.kt +++ b/app/src/main/java/ch/dissem/apps/abit/notification/ErrorNotification.kt @@ -55,6 +55,6 @@ class ErrorNotification(ctx: Context) : AbstractNotification(ctx) { override val notificationId = ERROR_NOTIFICATION_ID companion object { - val ERROR_NOTIFICATION_ID = 4 + const val ERROR_NOTIFICATION_ID = 4 } } diff --git a/app/src/main/java/ch/dissem/apps/abit/notification/NewMessageNotification.kt b/app/src/main/java/ch/dissem/apps/abit/notification/NewMessageNotification.kt index fc14f76..3328d26 100644 --- a/app/src/main/java/ch/dissem/apps/abit/notification/NewMessageNotification.kt +++ b/app/src/main/java/ch/dissem/apps/abit/notification/NewMessageNotification.kt @@ -128,7 +128,7 @@ class NewMessageNotification(ctx: Context) : AbstractNotification(ctx) { override val notificationId = NEW_MESSAGE_NOTIFICATION_ID companion object { - private val NEW_MESSAGE_NOTIFICATION_ID = 1 + private const val NEW_MESSAGE_NOTIFICATION_ID = 1 private val SPAN_EMPHASIS = StyleSpan(Typeface.BOLD) } } diff --git a/app/src/main/java/ch/dissem/apps/abit/repository/AndroidInventory.kt b/app/src/main/java/ch/dissem/apps/abit/repository/AndroidInventory.kt index b381654..673f246 100644 --- a/app/src/main/java/ch/dissem/apps/abit/repository/AndroidInventory.kt +++ b/app/src/main/java/ch/dissem/apps/abit/repository/AndroidInventory.kt @@ -54,7 +54,7 @@ class AndroidInventory(private val sql: SqlHelper) : Inventory { private fun getCache(stream: Long): MutableMap<InventoryVector, Long> { fun addToCache(stream: Long): MutableMap<InventoryVector, Long> { val result: MutableMap<InventoryVector, Long> = ConcurrentHashMap() - cache.put(stream, result) + cache[stream] = result val projection = arrayOf(COLUMN_HASH, COLUMN_EXPIRES) @@ -149,7 +149,7 @@ class AndroidInventory(private val sql: SqlHelper) : Inventory { sql.writableDatabase.insertOrThrow(TABLE_NAME, null, values) - getCache(objectMessage.stream).put(iv, objectMessage.expiresTime) + getCache(objectMessage.stream)[iv] = objectMessage.expiresTime } catch (e: SQLiteConstraintException) { LOG.trace(e.message, e) } diff --git a/app/src/main/java/ch/dissem/apps/abit/repository/AndroidProofOfWorkRepository.kt b/app/src/main/java/ch/dissem/apps/abit/repository/AndroidProofOfWorkRepository.kt index f7510c2..b6963a1 100644 --- a/app/src/main/java/ch/dissem/apps/abit/repository/AndroidProofOfWorkRepository.kt +++ b/app/src/main/java/ch/dissem/apps/abit/repository/AndroidProofOfWorkRepository.kt @@ -125,13 +125,13 @@ class AndroidProofOfWorkRepository(private val sql: SqlHelper) : ProofOfWorkRepo companion object { private val LOG = LoggerFactory.getLogger(AndroidProofOfWorkRepository::class.java) - private val TABLE_NAME = "POW" - private val COLUMN_INITIAL_HASH = "initial_hash" - private val COLUMN_DATA = "data" - private val COLUMN_VERSION = "version" - private val COLUMN_NONCE_TRIALS_PER_BYTE = "nonce_trials_per_byte" - private val COLUMN_EXTRA_BYTES = "extra_bytes" - private val COLUMN_EXPIRATION_TIME = "expiration_time" - private val COLUMN_MESSAGE_ID = "message_id" + private const val TABLE_NAME = "POW" + private const val COLUMN_INITIAL_HASH = "initial_hash" + private const val COLUMN_DATA = "data" + private const val COLUMN_VERSION = "version" + private const val COLUMN_NONCE_TRIALS_PER_BYTE = "nonce_trials_per_byte" + private const val COLUMN_EXTRA_BYTES = "extra_bytes" + private const val COLUMN_EXPIRATION_TIME = "expiration_time" + private const val COLUMN_MESSAGE_ID = "message_id" } } diff --git a/app/src/main/java/ch/dissem/apps/abit/repository/SqlHelper.kt b/app/src/main/java/ch/dissem/apps/abit/repository/SqlHelper.kt index 588b117..faa0205 100644 --- a/app/src/main/java/ch/dissem/apps/abit/repository/SqlHelper.kt +++ b/app/src/main/java/ch/dissem/apps/abit/repository/SqlHelper.kt @@ -90,7 +90,7 @@ class SqlHelper(private val ctx: Context) : SQLiteOpenHelper(ctx, DATABASE_NAME, companion object { // If you change the database schema, you must increment the database version. - private val DATABASE_VERSION = 7 - val DATABASE_NAME = "jabit.db" + private const val DATABASE_VERSION = 7 + const val DATABASE_NAME = "jabit.db" } } diff --git a/app/src/main/java/ch/dissem/apps/abit/service/BitmessageService.kt b/app/src/main/java/ch/dissem/apps/abit/service/BitmessageService.kt index 31c0a88..2ce3b3f 100644 --- a/app/src/main/java/ch/dissem/apps/abit/service/BitmessageService.kt +++ b/app/src/main/java/ch/dissem/apps/abit/service/BitmessageService.kt @@ -25,11 +25,9 @@ import android.net.ConnectivityManager import android.os.Handler import ch.dissem.apps.abit.notification.NetworkNotification import ch.dissem.apps.abit.notification.NetworkNotification.Companion.NETWORK_NOTIFICATION_ID -import ch.dissem.apps.abit.util.NetworkUtils import ch.dissem.apps.abit.util.Preferences import ch.dissem.bitmessage.BitmessageContext import ch.dissem.bitmessage.utils.Property -import org.jetbrains.anko.connectivityManager /** * Define a Service that returns an IBinder for the diff --git a/app/src/main/java/ch/dissem/apps/abit/service/ProofOfWorkService.kt b/app/src/main/java/ch/dissem/apps/abit/service/ProofOfWorkService.kt index 4d8b3e7..57365d8 100644 --- a/app/src/main/java/ch/dissem/apps/abit/service/ProofOfWorkService.kt +++ b/app/src/main/java/ch/dissem/apps/abit/service/ProofOfWorkService.kt @@ -19,7 +19,6 @@ package ch.dissem.apps.abit.service import android.app.Service import android.content.Intent import android.os.Binder -import android.os.IBinder import android.support.v4.content.ContextCompat import ch.dissem.apps.abit.notification.ProofOfWorkNotification import ch.dissem.apps.abit.notification.ProofOfWorkNotification.Companion.ONGOING_NOTIFICATION_ID diff --git a/app/src/main/java/ch/dissem/apps/abit/service/StartupNodeOnWifiService.kt b/app/src/main/java/ch/dissem/apps/abit/service/StartupNodeOnWifiService.kt index 0e1d557..5a3ee01 100644 --- a/app/src/main/java/ch/dissem/apps/abit/service/StartupNodeOnWifiService.kt +++ b/app/src/main/java/ch/dissem/apps/abit/service/StartupNodeOnWifiService.kt @@ -2,7 +2,6 @@ package ch.dissem.apps.abit.service import android.app.job.JobParameters import android.app.job.JobService -import android.content.Intent import android.os.Build import android.support.annotation.RequiresApi import ch.dissem.apps.abit.util.NetworkUtils diff --git a/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncService.kt b/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncService.kt index ba4c570..a1b581e 100644 --- a/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncService.kt +++ b/app/src/main/java/ch/dissem/apps/abit/synchronization/SyncService.kt @@ -18,7 +18,6 @@ package ch.dissem.apps.abit.synchronization import android.app.Service import android.content.Intent -import android.os.IBinder /** * Define a Service that returns an IBinder for the diff --git a/app/src/main/java/ch/dissem/apps/abit/util/Drawables.kt b/app/src/main/java/ch/dissem/apps/abit/util/Drawables.kt index 1aa4863..5905cbf 100644 --- a/app/src/main/java/ch/dissem/apps/abit/util/Drawables.kt +++ b/app/src/main/java/ch/dissem/apps/abit/util/Drawables.kt @@ -44,7 +44,7 @@ import java.io.ByteArrayOutputStream object Drawables { private val LOG = LoggerFactory.getLogger(Drawables::class.java) - private val QR_CODE_SIZE = 350 + private const val QR_CODE_SIZE = 350 fun addIcon(ctx: Context, menu: Menu, menuItem: Int, icon: IIcon): MenuItem { val item = menu.findItem(menuItem) diff --git a/app/src/main/java/ch/dissem/apps/abit/util/Observable.kt b/app/src/main/java/ch/dissem/apps/abit/util/Observable.kt index 1e35955..e384fde 100644 --- a/app/src/main/java/ch/dissem/apps/abit/util/Observable.kt +++ b/app/src/main/java/ch/dissem/apps/abit/util/Observable.kt @@ -25,7 +25,7 @@ class Observable<T>(value: T) { * To prevent memory leaks, the observer must be removed if it isn't used anymore. */ fun addObserver(key: Any, observer: (T) -> Unit) { - observers.put(key, observer) + observers[key] = observer } /** diff --git a/app/src/main/java/ch/dissem/apps/abit/util/PRNGFixes.java b/app/src/main/java/ch/dissem/apps/abit/util/PRNGFixes.java index 47fef8b..38bda8b 100644 --- a/app/src/main/java/ch/dissem/apps/abit/util/PRNGFixes.java +++ b/app/src/main/java/ch/dissem/apps/abit/util/PRNGFixes.java @@ -44,7 +44,7 @@ public final class PRNGFixes { private static final int VERSION_CODE_JELLY_BEAN = 16; private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18; private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL = - getBuildFingerprintAndDeviceSerial(); + getBuildFingerprintAndDeviceSerial(); /** * Hidden constructor to prevent instantiation. @@ -70,7 +70,7 @@ public final class PRNGFixes { */ private static void applyOpenSSLFix() throws SecurityException { if ((Build.VERSION.SDK_INT < VERSION_CODE_JELLY_BEAN) - || (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2)) { + || (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2)) { // No need to apply the fix return; } @@ -78,18 +78,18 @@ public final class PRNGFixes { try { // Mix in the device- and invocation-specific seed. Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto") - .getMethod("RAND_seed", byte[].class) - .invoke(null, (Object) generateSeed()); + .getMethod("RAND_seed", byte[].class) + .invoke(null, (Object) generateSeed()); // Mix output of Linux PRNG into OpenSSL's PRNG int bytesRead = (Integer) Class.forName( - "org.apache.harmony.xnet.provider.jsse.NativeCrypto") - .getMethod("RAND_load_file", String.class, long.class) - .invoke(null, "/dev/urandom", 1024); + "org.apache.harmony.xnet.provider.jsse.NativeCrypto") + .getMethod("RAND_load_file", String.class, long.class) + .invoke(null, "/dev/urandom", 1024); if (bytesRead != 1024) { throw new IOException( - "Unexpected number of bytes read from Linux PRNG: " - + bytesRead); + "Unexpected number of bytes read from Linux PRNG: " + + bytesRead); } } catch (Exception e) { throw new SecurityException("Failed to seed OpenSSL PRNG", e); @@ -104,7 +104,7 @@ public final class PRNGFixes { * @throws SecurityException if the fix is needed but could not be applied. */ private static void installLinuxPRNGSecureRandom() - throws SecurityException { + throws SecurityException { if (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2) { // No need to apply the fix return; @@ -113,11 +113,11 @@ public final class PRNGFixes { // Install a Linux PRNG-based SecureRandom implementation as the // default, if not yet installed. Provider[] secureRandomProviders = - Security.getProviders("SecureRandom.SHA1PRNG"); + Security.getProviders("SecureRandom.SHA1PRNG"); if ((secureRandomProviders == null) - || (secureRandomProviders.length < 1) - || (!LinuxPRNGSecureRandomProvider.class.equals( - secureRandomProviders[0].getClass()))) { + || (secureRandomProviders.length < 1) + || (!LinuxPRNGSecureRandomProvider.class.equals( + secureRandomProviders[0].getClass()))) { Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1); } @@ -126,10 +126,10 @@ public final class PRNGFixes { // by the Linux PRNG-based SecureRandom implementation. SecureRandom rng1 = new SecureRandom(); if (!LinuxPRNGSecureRandomProvider.class.equals( - rng1.getProvider().getClass())) { + rng1.getProvider().getClass())) { throw new SecurityException( - "new SecureRandom() backed by wrong Provider: " - + rng1.getProvider().getClass()); + "new SecureRandom() backed by wrong Provider: " + + rng1.getProvider().getClass()); } SecureRandom rng2; @@ -139,10 +139,10 @@ public final class PRNGFixes { throw new SecurityException("SHA1PRNG not available", e); } if (!LinuxPRNGSecureRandomProvider.class.equals( - rng2.getProvider().getClass())) { + rng2.getProvider().getClass())) { throw new SecurityException( - "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong" - + " Provider: " + rng2.getProvider().getClass()); + "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong" + + " Provider: " + rng2.getProvider().getClass()); } } @@ -152,11 +152,11 @@ public final class PRNGFixes { */ private static class LinuxPRNGSecureRandomProvider extends Provider { - public LinuxPRNGSecureRandomProvider() { + LinuxPRNGSecureRandomProvider() { super("LinuxPRNG", - 1.0, - "A Linux-specific random number provider that uses" - + " /dev/urandom"); + 1.0, + "A Linux-specific random number provider that uses" + + " /dev/urandom"); // Although /dev/urandom is not a SHA-1 PRNG, some apps // explicitly request a SHA1PRNG SecureRandom and we thus need to // prevent them from getting the default implementation whose output @@ -225,7 +225,7 @@ public final class PRNGFixes { // On a small fraction of devices /dev/urandom is not writable. // Log and ignore. Log.w(PRNGFixes.class.getSimpleName(), - "Failed to mix seed into " + URANDOM_FILE); + "Failed to mix seed into " + URANDOM_FILE); } finally { mSeeded = true; } @@ -249,7 +249,7 @@ public final class PRNGFixes { } } catch (IOException e) { throw new SecurityException( - "Failed to read from " + URANDOM_FILE, e); + "Failed to read from " + URANDOM_FILE, e); } } @@ -269,10 +269,10 @@ public final class PRNGFixes { // output being pulled into this process prematurely. try { sUrandomIn = new DataInputStream( - new FileInputStream(URANDOM_FILE)); + new FileInputStream(URANDOM_FILE)); } catch (IOException e) { throw new SecurityException("Failed to open " - + URANDOM_FILE + " for reading", e); + + URANDOM_FILE + " for reading", e); } } return sUrandomIn; @@ -297,7 +297,7 @@ public final class PRNGFixes { try { ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream(); DataOutputStream seedBufferOut = - new DataOutputStream(seedBuffer); + new DataOutputStream(seedBuffer); seedBufferOut.writeLong(System.currentTimeMillis()); seedBufferOut.writeLong(System.nanoTime()); seedBufferOut.writeInt(Process.myPid()); @@ -341,4 +341,4 @@ public final class PRNGFixes { throw new RuntimeException("UTF-8 encoding not supported"); } } -} \ No newline at end of file +} diff --git a/app/src/main/res/layout/contact_row.xml b/app/src/main/res/layout/contact_row.xml index 491f39f..3cf9f9d 100644 --- a/app/src/main/res/layout/contact_row.xml +++ b/app/src/main/res/layout/contact_row.xml @@ -37,11 +37,11 @@ android:layout_alignTop="@+id/avatar" android:layout_toEndOf="@+id/avatar" android:ellipsize="end" - android:lines="1" android:paddingBottom="0dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="0dp" + android:singleLine="true" android:textAppearance="?android:attr/textAppearanceMedium" android:textStyle="bold" tools:text="Name" /> @@ -53,9 +53,9 @@ android:layout_alignBottom="@+id/avatar" android:layout_toEndOf="@+id/avatar" android:ellipsize="marquee" - android:lines="1" android:paddingLeft="8dp" android:paddingRight="8dp" + android:singleLine="true" android:textAppearance="?android:attr/textAppearanceSmall" tools:text="BM-2cW0000000000000000000000000000000" /> diff --git a/app/src/main/res/layout/dialog_add_deterministic_identity.xml b/app/src/main/res/layout/dialog_add_deterministic_identity.xml index 5df7bfa..cdcfc76 100644 --- a/app/src/main/res/layout/dialog_add_deterministic_identity.xml +++ b/app/src/main/res/layout/dialog_add_deterministic_identity.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright 2016 Christian Basler ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,8 +14,7 @@ ~ limitations under the License. --> -<android.support.constraint.ConstraintLayout - xmlns:android="http://schemas.android.com/apk/res/android" +<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" @@ -34,13 +32,13 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" tools:layout_constraintLeft_creator="1" - tools:layout_constraintTop_creator="1"/> + tools:layout_constraintTop_creator="1" /> <android.support.design.widget.TextInputLayout android:id="@+id/label_wrapper" - android:layout_marginTop="24dp" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginTop="24dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@id/description"> @@ -48,7 +46,7 @@ android:id="@+id/label" android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="@string/label"/> + android:hint="@string/label" /> </android.support.design.widget.TextInputLayout> @@ -64,7 +62,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/passphrase" - android:inputType="textMultiLine"/> + android:inputType="textMultiLine" /> </android.support.design.widget.TextInputLayout> @@ -82,7 +80,8 @@ android:ems="10" android:hint="@string/number_of_identities" android:inputType="number" - android:text="1"/> + android:text="1" + tools:ignore="HardcodedText" /> </android.support.design.widget.TextInputLayout> @@ -92,7 +91,7 @@ android:layout_height="wrap_content" android:text="@string/shorter" app:layout_constraintLeft_toLeftOf="parent" - app:layout_constraintTop_toBottomOf="@id/number_of_identities_wrapper"/> + app:layout_constraintTop_toBottomOf="@id/number_of_identities_wrapper" /> <Button android:id="@+id/ok" @@ -103,7 +102,7 @@ android:text="@string/ok" android:textColor="@color/colorAccent" app:layout_constraintRight_toRightOf="parent" - app:layout_constraintTop_toBottomOf="@id/shorter"/> + app:layout_constraintTop_toBottomOf="@id/shorter" /> <Button android:id="@+id/dismiss" @@ -113,6 +112,6 @@ android:text="@string/cancel" android:textColor="@color/colorAccent" app:layout_constraintBottom_toBottomOf="@id/ok" - app:layout_constraintRight_toLeftOf="@id/ok"/> + app:layout_constraintRight_toLeftOf="@id/ok" /> </android.support.constraint.ConstraintLayout> diff --git a/app/src/main/res/layout/message_row.xml b/app/src/main/res/layout/message_row.xml index 9c9f88a..43cf5af 100644 --- a/app/src/main/res/layout/message_row.xml +++ b/app/src/main/res/layout/message_row.xml @@ -26,6 +26,7 @@ android:layout_height="match_parent" android:background="@drawable/bg_item_normal_state" android:clickable="true" + android:focusable="true" android:foreground="?attr/selectableItemBackground" tools:ignore="UselessParent"> diff --git a/app/src/main/res/layout/select_identity_row.xml b/app/src/main/res/layout/select_identity_row.xml index b65cce1..1c4df83 100644 --- a/app/src/main/res/layout/select_identity_row.xml +++ b/app/src/main/res/layout/select_identity_row.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- ~ Copyright 2016 Christian Basler ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,9 +15,9 @@ --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="64dp"> + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="64dp"> <CheckBox android:id="@+id/checkbox" @@ -31,21 +30,22 @@ android:paddingEnd="8dp" android:paddingStart="16dp" android:paddingTop="8dp" + android:singleLine="true" android:textAppearance="?android:attr/textAppearanceMedium" - tools:text="Name"/> + tools:text="Name" /> <TextView android:id="@+id/address" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_alignParentStart="true" android:layout_alignParentBottom="true" + android:layout_alignParentStart="true" android:ellipsize="marquee" - android:lines="1" android:paddingBottom="8dp" android:paddingEnd="8dp" android:paddingStart="48dp" + android:singleLine="true" android:textAppearance="?android:attr/textAppearanceSmall" - tools:text="BM-2cW0000000000000000000000000000000"/> + tools:text="BM-2cW0000000000000000000000000000000" /> </RelativeLayout> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index aa4baab..49a7b0c 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -5,7 +5,7 @@ <item name="android:activatedBackgroundIndicator">@drawable/bg_item_activated</item> <item name="android:textColor">@color/colorPrimaryText</item> <item name="android:textColorSecondary">@color/colorSecondaryText</item> - <item name="preferenceTheme">@style/PreferenceThemeOverlay</item> + <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> </style> <style name="CustomShowcaseTheme" parent="ShowcaseView"> diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml index 8fee7f3..e55b174 100644 --- a/app/src/main/res/xml/file_paths.xml +++ b/app/src/main/res/xml/file_paths.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> -<paths xmlns:android="http://schemas.android.com/apk/res/android"> +<paths> <files-path name="exports" path="exports/"/> </paths> diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 290ad1c..d62ac94 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -1,64 +1,58 @@ <?xml version="1.0" encoding="utf-8"?> -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> - <SwitchPreferenceCompat +<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <android.support.v7.preference.SwitchPreferenceCompat android:defaultValue="true" android:key="wifi_only" android:summary="@string/wifi_only_summary" - android:title="@string/wifi_only"/> - <SwitchPreferenceCompat + android:title="@string/wifi_only" /> + <android.support.v7.preference.SwitchPreferenceCompat android:defaultValue="true" android:key="request_acknowledgements" android:summary="@string/request_acknowledgements_summary" - android:title="@string/request_acknowledgements"/> - <EditTextPreference + android:title="@string/request_acknowledgements" /> + <android.support.v7.preference.EditTextPreference android:inputType="textUri" android:key="trusted_node" android:summary="@string/trusted_node_summary" - android:title="@string/trusted_node"/> - <EditTextPreference + android:title="@string/trusted_node" /> + <android.support.v7.preference.EditTextPreference android:defaultValue="120" android:inputType="number" android:key="sync_timeout" android:summary="@string/sync_timeout_summary" - android:title="@string/sync_timeout"/> - <SwitchPreferenceCompat + android:title="@string/sync_timeout" /> + <android.support.v7.preference.SwitchPreferenceCompat android:defaultValue="false" android:dependency="trusted_node" android:key="server_pow" android:summary="@string/server_pow_summary" - android:title="@string/server_pow" - /> - <Preference + android:title="@string/server_pow" /> + <android.support.v7.preference.Preference android:key="about" android:summary="@string/about_summary" - android:title="@string/about" - /> - <Preference + android:title="@string/about" /> + <android.support.v7.preference.Preference android:key="help_out" android:summary="@string/help_out_summary" android:title="@string/help_out"> <intent android:action="android.intent.action.VIEW" - android:data="@string/help_out_link"/> - </Preference> - <Preference + android:data="@string/help_out_link" /> + </android.support.v7.preference.Preference> + <android.support.v7.preference.Preference android:key="cleanup" - android:title="@string/cleanup" android:summary="@string/cleanup_summary" - /> - <Preference + android:title="@string/cleanup" /> + <android.support.v7.preference.Preference android:key="export" - android:title="@string/export_data" android:summary="@string/export_data_summary" - /> - <Preference + android:title="@string/export_data" /> + <android.support.v7.preference.Preference android:key="import" - android:title="@string/import_data" android:summary="@string/import_data_summary" - /> - <Preference + android:title="@string/import_data" /> + <android.support.v7.preference.Preference android:key="status" android:summary="@string/status_summary" - android:title="@string/status" - /> -</PreferenceScreen> + android:title="@string/status" /> +</android.support.v7.preference.PreferenceScreen> diff --git a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidAddressRepositoryTest.kt b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidAddressRepositoryTest.kt index 4d8d893..078c887 100644 --- a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidAddressRepositoryTest.kt +++ b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidAddressRepositoryTest.kt @@ -17,7 +17,7 @@ package ch.dissem.bitmessage.repository import android.os.Build -import ch.dissem.apps.abit.BuildConfig +import android.os.Build.VERSION_CODES.LOLLIPOP import ch.dissem.apps.abit.repository.AndroidAddressRepository import ch.dissem.apps.abit.repository.SqlHelper import ch.dissem.bitmessage.entity.BitmessageAddress @@ -32,7 +32,7 @@ import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) -@Config(sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP), packageName = "ch.dissem.apps.abit") +@Config(sdk = [LOLLIPOP], packageName = "ch.dissem.apps.abit") class AndroidAddressRepositoryTest : TestBase() { private val contactA = "BM-2cW7cD5cDQJDNkE7ibmyTxfvGAmnPqa9Vt" private val contactB = "BM-2cTtkBnb4BUYDndTKun6D9PjtueP2h1bQj" diff --git a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidInventoryTest.kt b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidInventoryTest.kt index 56adf7e..41ed627 100644 --- a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidInventoryTest.kt +++ b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidInventoryTest.kt @@ -17,7 +17,7 @@ package ch.dissem.bitmessage.repository import android.os.Build -import ch.dissem.apps.abit.BuildConfig +import android.os.Build.VERSION_CODES.LOLLIPOP import ch.dissem.apps.abit.repository.AndroidInventory import ch.dissem.apps.abit.repository.SqlHelper import ch.dissem.bitmessage.entity.BitmessageAddress @@ -40,7 +40,7 @@ import org.robolectric.annotation.Config import java.util.* @RunWith(RobolectricTestRunner::class) -@Config(sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP), packageName = "ch.dissem.apps.abit") +@Config(sdk = [LOLLIPOP], packageName = "ch.dissem.apps.abit") class AndroidInventoryTest : TestBase() { private lateinit var inventory: Inventory @@ -135,11 +135,12 @@ class AndroidInventoryTest : TestBase() { } private fun getObjectMessage(stream: Long, TTL: Long, payload: ObjectPayload) = ObjectMessage( - nonce = ByteArray(8), - expiresTime = now + TTL, - stream = stream, - payload = payload + nonce = ByteArray(8), + expiresTime = now + TTL, + stream = stream, + payload = payload ) - private val getPubkey: GetPubkey = GetPubkey(BitmessageAddress("BM-2cW7cD5cDQJDNkE7ibmyTxfvGAmnPqa9Vt")) + private val getPubkey: GetPubkey = + GetPubkey(BitmessageAddress("BM-2cW7cD5cDQJDNkE7ibmyTxfvGAmnPqa9Vt")) } diff --git a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidLabelRepositoryTest.kt b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidLabelRepositoryTest.kt index bde7bf6..5d01c70 100644 --- a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidLabelRepositoryTest.kt +++ b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidLabelRepositoryTest.kt @@ -17,6 +17,7 @@ package ch.dissem.bitmessage.repository import android.os.Build +import android.os.Build.VERSION_CODES.LOLLIPOP import ch.dissem.apps.abit.repository.AndroidLabelRepository import ch.dissem.apps.abit.repository.SqlHelper import ch.dissem.bitmessage.entity.valueobject.Label @@ -30,7 +31,7 @@ import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) -@Config(sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP), packageName = "ch.dissem.apps.abit") +@Config(sdk = [LOLLIPOP], packageName = "ch.dissem.apps.abit") class AndroidLabelRepositoryTest : TestBase() { private lateinit var repo: LabelRepository diff --git a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidMessageRepositoryTest.kt b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidMessageRepositoryTest.kt index 36d6da0..ead5c9d 100644 --- a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidMessageRepositoryTest.kt +++ b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidMessageRepositoryTest.kt @@ -16,7 +16,7 @@ package ch.dissem.bitmessage.repository -import android.os.Build +import android.os.Build.VERSION_CODES.LOLLIPOP import ch.dissem.apps.abit.repository.AndroidAddressRepository import ch.dissem.apps.abit.repository.AndroidLabelRepository import ch.dissem.apps.abit.repository.AndroidMessageRepository @@ -31,7 +31,6 @@ import ch.dissem.bitmessage.entity.valueobject.ExtendedEncoding import ch.dissem.bitmessage.entity.valueobject.Label import ch.dissem.bitmessage.entity.valueobject.PrivateKey import ch.dissem.bitmessage.entity.valueobject.extended.Message -import ch.dissem.bitmessage.ports.LabelRepository import ch.dissem.bitmessage.ports.MessageRepository import ch.dissem.bitmessage.utils.UnixTime import org.hamcrest.BaseMatcher @@ -48,7 +47,7 @@ import org.robolectric.annotation.Config import java.util.* @RunWith(RobolectricTestRunner::class) -@Config(sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP), packageName = "ch.dissem.apps.abit") +@Config(sdk = [LOLLIPOP], packageName = "ch.dissem.apps.abit") class AndroidMessageRepositoryTest : TestBase() { private lateinit var contactA: BitmessageAddress private lateinit var contactB: BitmessageAddress diff --git a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidNodeRegistryTest.kt b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidNodeRegistryTest.kt index b3fc93a..acaeeff 100644 --- a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidNodeRegistryTest.kt +++ b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidNodeRegistryTest.kt @@ -17,7 +17,7 @@ package ch.dissem.bitmessage.repository import android.os.Build -import ch.dissem.apps.abit.BuildConfig +import android.os.Build.VERSION_CODES.LOLLIPOP import ch.dissem.apps.abit.repository.AndroidNodeRegistry import ch.dissem.apps.abit.repository.SqlHelper import ch.dissem.bitmessage.entity.valueobject.NetworkAddress @@ -39,7 +39,7 @@ import java.util.* * as the initial nodes' IP addresses are determined by DNS lookup. */ @RunWith(RobolectricTestRunner::class) -@Config(sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP), packageName = "ch.dissem.apps.abit") +@Config(sdk = [LOLLIPOP], packageName = "ch.dissem.apps.abit") class AndroidNodeRegistryTest : TestBase() { private lateinit var registry: NodeRegistry diff --git a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidProofOfWorkRepositoryTest.kt b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidProofOfWorkRepositoryTest.kt index 274e672..5c06974 100644 --- a/app/src/test/java/ch/dissem/bitmessage/repository/AndroidProofOfWorkRepositoryTest.kt +++ b/app/src/test/java/ch/dissem/bitmessage/repository/AndroidProofOfWorkRepositoryTest.kt @@ -46,7 +46,7 @@ import kotlin.properties.Delegates * @author Christian Basler */ @RunWith(RobolectricTestRunner::class) -@Config(sdk = intArrayOf(LOLLIPOP), packageName = "ch.dissem.apps.abit") +@Config(sdk = [LOLLIPOP], packageName = "ch.dissem.apps.abit") class AndroidProofOfWorkRepositoryTest : TestBase() { private lateinit var repo: ProofOfWorkRepository private lateinit var addressRepo: AddressRepository