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 @@ - + - - - - - - - - - + + + + + + + + + + android:supportsRtl="true" + android:theme="@style/AppTheme"> - + - + + android:value=".MainActivity" /> + android:value=".MainActivity" /> + android:theme="@style/Theme.AppCompat.Light.Dialog" /> + android:value=".MainActivity" /> - + - - - + + + - + - + - + - + - + - + - + - + - - - + + + - - + + + android:value=".MainActivity" /> - + + android:scheme="file" /> - - + + + android:exported="false" /> + android:exported="false" /> + android:syncable="true" /> - + + android:resource="@xml/authenticator" /> - + + android:resource="@xml/syncadapter" /> + android:exported="false" /> - + - + + - + + + android:exported="true" + android:permission="android.permission.BIND_JOB_SERVICE" /> + android:value=".MainActivity" /> 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/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..c248aef 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,72 +57,107 @@ 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") - }.invoke() + } ?: throw IllegalStateException("No identity set for ComposeMessageFragment") + 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) - 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) + } } } } @@ -146,18 +186,17 @@ 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) + builder = Plaintext.Builder(BROADCAST) } else { val inputString = recipient_input.text.toString() if (recipient == null || recipient?.toString() != inputString) { @@ -175,42 +214,69 @@ 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) + .to(recipient) } + val sender = sender_input.selectedItem as? ch.dissem.bitmessage.entity.BitmessageAddress + sender?.let { builder.from(it) } 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/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 { +interface ListHolder { 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 2f1d3aa..ae95bde 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,19 +486,29 @@ 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) } } fun setDetailView(fragment: Fragment) { if (hasDetailPane) { - supportFragmentManager.beginTransaction() + supportFragmentManager + .beginTransaction() .replace(R.id.message_detail_container, fragment) .commit() } @@ -474,15 +519,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/app/src/main/java/ch/dissem/apps/abit/MessageDetailFragment.kt b/app/src/main/java/ch/dissem/apps/abit/MessageDetailFragment.kt index ff630b3..6e08ad2 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() @@ -274,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/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<BitmessageAddress>, + private val slim: Boolean = false +) : + BaseAdapter(), Filterable { private val inflater = LayoutInflater.from(ctx) - private val originalData = Singleton.getAddressRepository(ctx).getContacts() private var data: List<BitmessageAddress> = 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<ImageView>(R.id.avatar)!! - val name = view.findViewById<TextView>(R.id.name)!! - val address = view.findViewById<TextView>(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<BitmessageAddress>() 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/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/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 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright 2015 Christian Basler + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <ImageView + android:id="@+id/avatar" + android:layout_width="32dp" + android:layout_height="32dp" + android:layout_alignParentStart="true" + android:layout_alignParentTop="true" + android:layout_margin="4dp" + android:src="@color/colorAccent" + tools:ignore="ContentDescription" /> + + <TextView + android:id="@+id/name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_toEndOf="@+id/avatar" + android:ellipsize="end" + android:lines="1" + android:paddingBottom="0dp" + android:paddingEnd="4dp" + android:paddingStart="4dp" + android:paddingTop="0dp" + android:textAppearance="?android:attr/textAppearanceMedium" + tools:text="Name" /> + +</RelativeLayout> 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/fragment_compose_message.xml b/app/src/main/res/layout/fragment_compose_message.xml index affc95b..afdbd77 100644 --- a/app/src/main/res/layout/fragment_compose_message.xml +++ b/app/src/main/res/layout/fragment_compose_message.xml @@ -1,46 +1,68 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fillViewport="true"> - <android.support.design.widget.TextInputLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="4dp"> - - <AutoCompleteTextView - android:id="@+id/recipient_input" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:hint="@string/to" - android:inputType="textNoSuggestions" - android:maxLines="1"/> - - </android.support.design.widget.TextInputLayout> - - <android.support.design.widget.TextInputLayout - android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <EditText - android:id="@+id/subject_input" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:hint="@string/subject" - android:inputType="textEmailSubject" - android:textAppearance="?android:attr/textAppearanceLarge"/> - - </android.support.design.widget.TextInputLayout> - - <EditText - android:id="@+id/body_input" + <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" - android:layout_weight="1" - android:gravity="start|top" - android:hint="@string/compose_body_hint" - android:inputType="textMultiLine|textCapSentences" - android:scrollbars="vertical"/> + android:orientation="vertical"> -</LinearLayout> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:labelFor="@id/sender_input" + android:padding="4dp" + android:text="@string/from" + android:textColor="#9b9b9b" + android:textSize="12sp" /> + + <Spinner + android:id="@+id/sender_input" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <android.support.design.widget.TextInputLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="4dp"> + + <AutoCompleteTextView + android:id="@+id/recipient_input" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/to" + android:inputType="textNoSuggestions" + android:maxLines="1" /> + + </android.support.design.widget.TextInputLayout> + + <android.support.design.widget.TextInputLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <EditText + android:id="@+id/subject_input" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/subject" + android:inputType="textEmailSubject" + android:textAppearance="?android:attr/textAppearanceLarge" /> + + </android.support.design.widget.TextInputLayout> + + <EditText + android:id="@+id/body_input" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="start|top" + android:hint="@string/compose_body_hint" + android:inputType="textMultiLine|textCapSentences" + android:scrollbars="none" + tools:ignore="InefficientWeight" /> + + </LinearLayout> +</ScrollView> 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-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 <string name="import_data">Import</string> <string name="import_data_summary">Nachrichten und Kontakte importieren (aber keine Identitäten)</string> <string name="select_encoding">Kodierung auswählen</string> + <string name="from">Von</string> </resources> 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 <string name="request_acknowledgements_summary">Acknowledges allow making sure a message was received, but require additional time to send</string> <string name="got_it">Got it</string> <string name="select_encoding">Select encoding</string> + <string name="from">From</string> </resources> 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 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()