From 66c8536a845fc364d3d422e501dbf39129c8efd1 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Fri, 9 Feb 2018 21:48:09 +0000 Subject: [PATCH 01/20] Added translation using Weblate (French) --- app/src/main/res/values-fr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/src/main/res/values-fr/strings.xml diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml new file mode 100644 index 0000000..a6b3dae --- /dev/null +++ b/app/src/main/res/values-fr/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From d611bd13bc885266f49f77334ce74babbb88fbb1 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Sat, 10 Feb 2018 22:51:16 +0000 Subject: [PATCH 02/20] Translated using Weblate (French) Currently translated at 8.8% (11 of 124 strings) Translation: Abit/App Translate-URL: http://translations.dissem.ch/projects/abit/app/fr/ --- app/src/main/res/values-fr/strings.xml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index a6b3dae..fb0f0d0 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1,2 +1,13 @@ - - \ No newline at end of file + +Abit + Un client Bitmessage pour Android + Message + Abonnement + Chan + Identité + Contact + Nœud de bitmessage + Paramètres + Seulement Wi-Fi + Ne vous connectez pas au réseau mobile + From 99b2d1903e98ff23c80335677a959b74ab68596a Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Sun, 11 Feb 2018 10:03:03 +0000 Subject: [PATCH 03/20] Added translation using Weblate (Arabic) --- app/src/main/res/values-ar/strings.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/src/main/res/values-ar/strings.xml diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml new file mode 100644 index 0000000..a6b3dae --- /dev/null +++ b/app/src/main/res/values-ar/strings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file From f481914a65d513d8526ffcbffc430cad8eb233b9 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Tue, 13 Feb 2018 07:24:24 +0100 Subject: [PATCH 04/20] 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 05/20] 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 06/20] 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 07/20] 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 08/20] 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 From c750e2004a68b23d10c003cf25f8dbe6c7f065a2 Mon Sep 17 00:00:00 2001 From: NourEddine <noureddine1x1@gmail.com> Date: Sun, 11 Feb 2018 19:14:22 +0000 Subject: [PATCH 09/20] Translated using Weblate (Arabic) Currently translated at 31.4% (39 of 124 strings) Translation: Abit/App Translate-URL: http://translations.dissem.ch/projects/abit/app/ar/ --- app/src/main/res/values-ar/strings.xml | 44 ++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index a6b3dae..c5d3f5c 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -1,2 +1,42 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources></resources> \ No newline at end of file +<?xml version='1.0' encoding='UTF-8'?> +<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name">Abit</string> + <string name="about_app">عميل Bitmessage أندرويد</string> + <string name="title_message_detail">رسالة</string> + <string name="title_subscription_detail">اشتراك</string> + <string name="title_chan_detail">قناة</string> + <string name="title_identity_detail">هوية</string> + <string name="title_contact_detail">جهة إتصال</string> + <string name="bitmessage_full_node">عقدة Bitmessage</string> + <string name="settings">إعدادات</string> + <string name="wifi_only">Wi-Fi فقط</string> + <string name="wifi_only_summary">منع الإتصال من خلال بيانات الهاتف</string> + <string name="to">إلى</string> + <string name="subject">الموضوع</string> + <string name="manage_identity">إدارة الهويات</string> + <string name="add_identity">إضافة هوية</string> + <string name="add_identity_summary">إنشاء هوية جديدة</string> + <string name="create_identity_description">إنشاء هوية جديدة عشوائية</string> + <string name="import_identity_description">إستيراد هوية موجودة من PyBitmessage او من تصدير</string> + <string name="add_deterministic_address">هوية حتمية</string> + <string name="add_deterministic_address_description">إنشاء أو إعادة إنشاء هوية حتمية</string> + <string name="add_chan">إضافة قناة</string> + <string name="add_chan_description">إنشاء أو الإنضمام إلى قناة</string> + <string name="title_activity_open_bitmessage_link">إستيراد جهة اتصال</string> + + <string name="subscribe">إشتراك</string> + <string name="do_import">استيراد</string> + <string name="cancel">إلغاء</string> + <string name="n_new_messages" tools:ignore="PluralsCandidate">رسائل جديدة</string> + <string name="reply">رد</string> + <string name="delete">حذف</string> + <string name="empty_trash">أفرغ المهملات</string> + <string name="trusted_node">عقدة موثوقة</string> + <string name="trusted_node_summary">استخدام العقدة في التزامن</string> + <string name="write_message">كتابة رسالة</string> + <string name="full_node">عقدة كاملة</string> + <string name="send">أرسل</string> + <string name="connection_info_disconnected">غير متصل</string> + <string name="connection_info_pending">يتصل…</string> + <string name="proof_of_work_title">إثبات العمل</string> + <string name="proof_of_work_text_0">جاري إثبات العمل لإرسال الرسالة</string> + </resources> From d98b800249d5339f6aea44f0e9d7e860181c95be Mon Sep 17 00:00:00 2001 From: Christian Basler <chrigu@dissem.ch> Date: Tue, 13 Feb 2018 10:32:28 +0000 Subject: [PATCH 10/20] Translated using Weblate (French) Currently translated at 99.1% (123 of 124 strings) Translation: Abit/App Translate-URL: http://translations.dissem.ch/projects/abit/app/fr/ --- app/src/main/res/values-fr/strings.xml | 119 ++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index fb0f0d0..aaa2d0c 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1,13 +1,126 @@ <?xml version='1.0' encoding='UTF-8'?> -<resources><string name="app_name">Abit</string> +<resources xmlns:tools="http://schemas.android.com/tools"><string name="app_name">Abit</string> <string name="about_app">Un client Bitmessage pour Android</string> <string name="title_message_detail">Message</string> <string name="title_subscription_detail">Abonnement</string> - <string name="title_chan_detail">Chan</string> + <string name="title_chan_detail">Canal</string> <string name="title_identity_detail">Identité</string> <string name="title_contact_detail">Contact</string> <string name="bitmessage_full_node">Nœud de bitmessage</string> <string name="settings">Paramètres</string> <string name="wifi_only">Seulement Wi-Fi</string> <string name="wifi_only_summary">Ne vous connectez pas au réseau mobile</string> - </resources> + <string name="to">A</string> + <string name="subject">Objet</string> + <string name="manage_identity">Gérer l\'identité</string> + <string name="add_identity">Ajouter une identité</string> + <string name="add_identity_summary">Créer une nouvelle identité</string> + <string name="create_identity_description">Créer une nouvelle identité aléatoire</string> + <string name="import_identity_description">Importation d\'une identité existante de PyBitmessage ou d\'une exportation</string> + <string name="add_deterministic_address">Identité déterministe</string> + <string name="add_deterministic_address_description">Créer ou recréer une identité déterministe</string> + <string name="add_chan">Ajouter un canal</string> + <string name="add_chan_description">Créer ou rejoindre un canal</string> + <string name="title_activity_open_bitmessage_link">Importation de contact</string> + + <string name="connection_info_1">"Flux nº%1$d: une connexion"</string> + <string name="connection_info_n" tools:ignore="PluralsCandidate">"Flux nº%1$d: %2$d connexions"</string> + <string name="label">Étiquette</string> + <string name="subscribe">Inscrivez-vous</string> + <string name="do_import">Importation</string> + <string name="cancel">Annuler</string> + <string name="broadcast">Diffusion</string> + <string name="n_new_messages" tools:ignore="PluralsCandidate">%d messages nouveaux</string> + <string name="reply">Répondre</string> + <string name="delete">Supprimer</string> + <string name="mark_unread">Marquer non lu</string> + <string name="archive">Archive</string> + <string name="stream_number">"Flux nº%d"</string> + <string name="trusted_node">Nœud de confiance</string> + <string name="trusted_node_summary">Cette adresse est utilisée pour la synchronisation</string> + <string name="sync_timeout">Limitation du temps de synchronisation</string> + <string name="write_message">Écrire un message</string> + <string name="full_node">Nœud actif</string> + <string name="send">Transmission</string> + <string name="connection_info_disconnected">Déconnecté</string> + <string name="connection_info_pending">La connexion est établie…</string> + <string name="proof_of_work_title">Preuve de travail</string> + <string name="proof_of_work_text_0">Faire du travail pour envoyer la message</string> + <string name="proof_of_work_text_n" tools:ignore="PluralsCandidate">Faire du travail pour envoyer la message (%1$d en file d\'attente)</string> + <string name="error_invalid_sync_port">Port non valide dans les paramètres de synchronisation: %s</string> + <string name="compose_body_hint">Écrire un message</string> + <string name="contacts_and_subscriptions">Contacts</string> + <string name="subscribed">Souscrit</string> + <string name="full_node_warning">L\'exécution d\'un nœud Bitmessage actif consomme beaucoup de trafic, ce qui peut coûter cher sur un réseau mobile. Êtes-vous sûr de vouloir démarrer un nœud actif?</string> + <string name="about">À propos d\'Abit</string> + <string name="about_summary">Les dépendances Open Source.</string> + <string name="title_activity_status">Déboguage</string> + <string name="status">Déboguage</string> + <string name="status_summary">Informations techniques</string> + <string name="alias_default_identity">Moi</string> + <string name="pubkey_available">Clé publique disponible</string> + <string name="pubkey_not_available">Clé publique pas encore disponible</string> + <string name="alt_qr_code">Code QR</string> + <string name="add_identity_warning">Avoir plus d\'identités exigera plus de ressources. Si vous êtes sûr de vouloir ajouter une identité, veuillez choisir la procédure:</string> + <string name="delete_identity_warning">Êtes-vous sûr de vouloir effacer cette identité? Les messages envoyés à cette adresse ne peuvent plus être reçus et il n\'est pas possible d\'annuler cette action.</string> + <string name="delete_contact_warning">Êtes-vous sûr de vouloir supprimer ce contact?</string> + <string name="scan_qr_code">Scanner code QR</string> + <string name="create_contact">Créer un contact</string> + <string name="full_node_description">Vous ne pouvez pas recevoir ou envoyer de messages sans lancer un nœud actif. Mais sachez que cela utilise beaucoup de ressources et de trafic internet. Comme alternative, vous pouvez configurer un nœud de confiance dans les paramètres, mais à partir de maintenant vous devrez déployer votre propre nœud.</string> + <string name="address">Adresse Bitmessage</string> + <string name="error_illegal_address">C\'est peut-être une faute de frappe</string> + <string name="export">Exportation</string> + <string name="confirm_export">Voulez-vous vraiment exporter votre identité? L\'exportation contiendra les clés privées non chiffrées.</string> + <string name="passphrase">Phrase de passe</string> + <string name="help_out">Soutenir le développement</string> + <string name="help_out_summary">Apprenez comment soutenir le développement d\'Abit</string> + <string name="toast_long_running_operation">Cela peut prendre quelques minutes</string> + <string name="toast_identity_created">Identité créée</string> + <string name="toast_identities_created">Les identités ont été créées</string> + <string name="toast_chan_created">Canal créé</string> + <string name="deterministic_address_warning">N\'oubliez pas ces paramètres et assurez-vous qu\'ils sont corrects lorsque vous recréez une adresse déterministe.</string> + <string name="number_of_identities">Nombre d\'identités à créer</string> + <string name="shorter">Recherche d\'adresses plus courtes</string> + <string name="wif_string">WIF / contenu de ‘keys.dat’</string> + <string name="next">Continuer</string> + <string name="title_import_identity">Importation d\'identité</string> + <string name="open_file">Ouvrir un fichier</string> + <string name="error_loading_data">Erreur lors du chargement des données</string> + <string name="select_file_title">Sélectionnez un fichier</string> + <string name="select_identities_to_import">Veuillez sélectionner les identités à importer:</string> + <string name="import_input_description">Vous pouvez simplement insérer le contenu d\'une exportation ou d\'un fichier \'keys.dat\'</string> + <string name="full_node_stop">arrêter le nœud</string> + <string name="full_node_restart">redémarrer le nœud</string> + <string name="use_mobile_network">Utiliser le réseau mobile</string> + <string name="personal_message">Message</string> + <string name="empty_trash">Vider les ordures</string> + <string name="sync_timeout_summary">Délai d\'expiration en secondes</string> + <string name="server_pow">POW sur le serveur</string> + <string name="server_pow_summary">Le nœud de confiance fait la preuve de travail</string> + <string name="share">Partager</string> + <string name="compose_message">Composer</string> + <string name="no_identity_warning">Veuillez réessayer dès qu\'une identité est disponible.</string> + <string name="status_public_key">clé publique demandée</string> + <string name="status_sent_acknowledged">Réception confirmée</string> + <string name="status_draft">brouillon</string> + <string name="status_sent">envoyé</string> + <string name="status_received">reçu</string> + <string name="outbox">Boîte d\'envoi</string> + <string name="error_unsupported_encoding">Encodage non supporté \'%s\', \'SIMPLE\' est utilisé.</string> + <string name="select_encoding_warning">\'EXTENDED\' est un nouveau format de message qui ne fonctionne pas encore partout, mais qui a des avantages intéressants. Sélectionnez \'SIMPLE\' pour être sûr.</string> + <string name="select_encoding_title">Sélectionner le codage des messages</string> + <string name="cleanup">Nettoyage</string> + <string name="cleanup_summary">Supprimer les entrées d\'inventaire obsolètes</string> + <string name="cleanup_notification_start">Démarrage du nettoyage</string> + <string name="cleanup_notification_end">Nettoyage terminé</string> + <string name="wait_for_wifi">Attendez la connexion Wi-Fi</string> + <string name="error_msg_recipient_missing">Veuillez indiquer un destinataire</string> + <string name="export_data">Exportation</string> + <string name="export_data_summary">Exporter tous les messages et contacts (mais pas les identités)</string> + <string name="import_data">Importation</string> + <string name="import_data_summary">Importer des messages et des contacts (mais pas des identités)</string> + <string name="request_acknowledgements">Demande d\'accusés de réception</string> + <string name="request_acknowledgements_summary">Les accusés de réception permettent de s\'assurer qu\'un message a bien été reçu, mais il faut plus de temps pour l\'envoyer</string> + <string name="got_it">J\'ai compris</string> + <string name="select_encoding">Choix du codage</string> +</resources> From 46bbd597122925a112ccc45e877245aae3f8e1a9 Mon Sep 17 00:00:00 2001 From: Christian Basler <chrigu@dissem.ch> Date: Tue, 20 Feb 2018 17:07:35 +0000 Subject: [PATCH 11/20] Translated using Weblate (French) Currently translated at 100.0% (125 of 125 strings) Translation: Abit/App Translate-URL: http://translations.dissem.ch/projects/abit/app/fr/ --- app/src/main/res/values-fr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index aaa2d0c..40f01b6 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -123,4 +123,6 @@ <string name="request_acknowledgements_summary">Les accusés de réception permettent de s\'assurer qu\'un message a bien été reçu, mais il faut plus de temps pour l\'envoyer</string> <string name="got_it">J\'ai compris</string> <string name="select_encoding">Choix du codage</string> +<string name="help_out_link">https://dissem.github.io/Abit/aider</string> + <string name="from">De</string> </resources> From 4f1ef4407c7cfff8d174ca8f70af2c26a567f278 Mon Sep 17 00:00:00 2001 From: Christian Basler <chrigu@dissem.ch> Date: Tue, 20 Feb 2018 17:17:36 +0000 Subject: [PATCH 12/20] Translated using Weblate (French) Currently translated at 100.0% (125 of 125 strings) Translation: Abit/App Translate-URL: http://translations.dissem.ch/projects/abit/app/fr/ --- app/src/main/res/values-fr/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 40f01b6..345307c 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -47,11 +47,11 @@ <string name="proof_of_work_title">Preuve de travail</string> <string name="proof_of_work_text_0">Faire du travail pour envoyer la message</string> <string name="proof_of_work_text_n" tools:ignore="PluralsCandidate">Faire du travail pour envoyer la message (%1$d en file d\'attente)</string> - <string name="error_invalid_sync_port">Port non valide dans les paramètres de synchronisation: %s</string> + <string name="error_invalid_sync_port">Port non valide dans les paramètres de synchronisation : %s</string> <string name="compose_body_hint">Écrire un message</string> <string name="contacts_and_subscriptions">Contacts</string> <string name="subscribed">Souscrit</string> - <string name="full_node_warning">L\'exécution d\'un nœud Bitmessage actif consomme beaucoup de trafic, ce qui peut coûter cher sur un réseau mobile. Êtes-vous sûr de vouloir démarrer un nœud actif?</string> + <string name="full_node_warning">L\'exécution d\'un nœud Bitmessage actif consomme beaucoup de trafic, ce qui peut coûter cher sur un réseau mobile. Êtes-vous sûr de vouloir démarrer un nœud actif ?</string> <string name="about">À propos d\'Abit</string> <string name="about_summary">Les dépendances Open Source.</string> <string name="title_activity_status">Déboguage</string> @@ -61,8 +61,8 @@ <string name="pubkey_available">Clé publique disponible</string> <string name="pubkey_not_available">Clé publique pas encore disponible</string> <string name="alt_qr_code">Code QR</string> - <string name="add_identity_warning">Avoir plus d\'identités exigera plus de ressources. Si vous êtes sûr de vouloir ajouter une identité, veuillez choisir la procédure:</string> - <string name="delete_identity_warning">Êtes-vous sûr de vouloir effacer cette identité? Les messages envoyés à cette adresse ne peuvent plus être reçus et il n\'est pas possible d\'annuler cette action.</string> + <string name="add_identity_warning">Avoir plus d\'identités exigera plus de ressources. Si vous êtes sûr de vouloir ajouter une identité, veuillez choisir la procédure :</string> + <string name="delete_identity_warning">Êtes-vous sûr de vouloir effacer cette identité ? Les messages envoyés à cette adresse ne peuvent plus être reçus et il n\'est pas possible d\'annuler cette action.</string> <string name="delete_contact_warning">Êtes-vous sûr de vouloir supprimer ce contact?</string> <string name="scan_qr_code">Scanner code QR</string> <string name="create_contact">Créer un contact</string> @@ -70,7 +70,7 @@ <string name="address">Adresse Bitmessage</string> <string name="error_illegal_address">C\'est peut-être une faute de frappe</string> <string name="export">Exportation</string> - <string name="confirm_export">Voulez-vous vraiment exporter votre identité? L\'exportation contiendra les clés privées non chiffrées.</string> + <string name="confirm_export">Voulez-vous vraiment exporter votre identité ? L\'exportation contiendra les clés privées non chiffrées.</string> <string name="passphrase">Phrase de passe</string> <string name="help_out">Soutenir le développement</string> <string name="help_out_summary">Apprenez comment soutenir le développement d\'Abit</string> @@ -87,7 +87,7 @@ <string name="open_file">Ouvrir un fichier</string> <string name="error_loading_data">Erreur lors du chargement des données</string> <string name="select_file_title">Sélectionnez un fichier</string> - <string name="select_identities_to_import">Veuillez sélectionner les identités à importer:</string> + <string name="select_identities_to_import">Veuillez sélectionner les identités à importer :</string> <string name="import_input_description">Vous pouvez simplement insérer le contenu d\'une exportation ou d\'un fichier \'keys.dat\'</string> <string name="full_node_stop">arrêter le nœud</string> <string name="full_node_restart">redémarrer le nœud</string> From 61e0a12a504e6650961e210d6dda2c4b0c8c4595 Mon Sep 17 00:00:00 2001 From: Christian Basler <chrigu.meyer@gmail.com> Date: Tue, 20 Feb 2018 22:48:39 +0100 Subject: [PATCH 13/20] Don't show addresses without alias as contacts Those normally aren't of interest, and can now be retrieved via message. --- .../apps/abit/repository/AndroidAddressRepository.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/ch/dissem/apps/abit/repository/AndroidAddressRepository.kt b/app/src/main/java/ch/dissem/apps/abit/repository/AndroidAddressRepository.kt index 60623f2..3cadaf3 100644 --- a/app/src/main/java/ch/dissem/apps/abit/repository/AndroidAddressRepository.kt +++ b/app/src/main/java/ch/dissem/apps/abit/repository/AndroidAddressRepository.kt @@ -68,15 +68,15 @@ class AndroidAddressRepository(private val sql: SqlHelper) : AddressRepository { * Returns the contacts in the following order: * * * Subscribed addresses come first - * * Addresses with Aliases (alphabetically) - * * Addresses (alphabetically) + * * Addresses with aliases (alphabetically) + * * Addresses without aliases are omitted * * * @return the ordered list of ids (address strings) */ fun getContactIds(): List<String> = findIds( - "private_key IS NULL OR chan = '1'", - "$COLUMN_SUBSCRIBED DESC, $COLUMN_ALIAS IS NULL, $COLUMN_ALIAS, $COLUMN_ADDRESS" + "($COLUMN_PRIVATE_KEY IS NULL OR $COLUMN_CHAN = '1') AND $COLUMN_ALIAS IS NOT NULL", + "$COLUMN_SUBSCRIBED DESC, $COLUMN_ALIAS, $COLUMN_ADDRESS" ) private fun findIds(where: String, orderBy: String): List<String> { From c1af65732a64cfb888e3604de8014a6e7d12ec89 Mon Sep 17 00:00:00 2001 From: Christian Basler <chrigu.meyer@gmail.com> Date: Wed, 21 Feb 2018 15:05:08 +0100 Subject: [PATCH 14/20] Improve translations Moved labels.xml into strings.xml as they are handled by Weblate and it was a mess anyway. --- app/src/main/res/values-ar/strings.xml | 8 +++++++- app/src/main/res/values-de/labels.xml | 25 ------------------------- app/src/main/res/values-de/strings.xml | 9 ++++++++- app/src/main/res/values-fr/strings.xml | 9 ++++++++- app/src/main/res/values/labels.xml | 25 ------------------------- app/src/main/res/values/strings.xml | 9 ++++++++- 6 files changed, 31 insertions(+), 54 deletions(-) delete mode 100644 app/src/main/res/values-de/labels.xml delete mode 100644 app/src/main/res/values/labels.xml diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index c5d3f5c..986d7f2 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -39,4 +39,10 @@ <string name="connection_info_pending">يتصل…</string> <string name="proof_of_work_title">إثبات العمل</string> <string name="proof_of_work_text_0">جاري إثبات العمل لإرسال الرسالة</string> - </resources> + <string name="inbox">علبة الوارد</string> + <string name="draft">مسودات</string> + <string name="sent">تاريخ الإرسال</string> + <string name="unread">غير مقروء</string> + <string name="trash">مُهملات</string> + <string name="label">تسمية</string> +</resources> diff --git a/app/src/main/res/values-de/labels.xml b/app/src/main/res/values-de/labels.xml deleted file mode 100644 index d62843a..0000000 --- a/app/src/main/res/values-de/labels.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?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. - --> - -<resources> - <string name="inbox">Posteingang</string> - <string name="draft">Entwürfe</string> - <string name="sent">Gesendet</string> - <string name="unread">Ungelesen</string> - <string name="trash">Papierkorb</string> - <string name="broadcasts">Broadcasts</string> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 4a9cc7e..086c834 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -104,7 +104,6 @@ Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfigu <string name="title_chan_detail">Chan</string> <string name="title_contact_detail">Kontakt</string> <string name="title_identity_detail">Identität</string> - <string name="outbox">Postausgang</string> <string name="status_draft">Entwurf</string> <string name="status_public_key">öffentlicher Schlüssel angefordert</string> <string name="status_received">empfangen</string> @@ -128,4 +127,12 @@ Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfigu <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> + <string name="invalid_wif_file">Die Datei kann nicht verarbeitet werden</string> + <string name="inbox">Posteingang</string> + <string name="outbox">Postausgang</string> + <string name="draft">Entwürfe</string> + <string name="sent">Gesendet</string> + <string name="unread">Ungelesen</string> + <string name="trash">Papierkorb</string> + <string name="broadcasts">Broadcasts</string> </resources> diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 345307c..2e872e0 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -105,7 +105,6 @@ <string name="status_draft">brouillon</string> <string name="status_sent">envoyé</string> <string name="status_received">reçu</string> - <string name="outbox">Boîte d\'envoi</string> <string name="error_unsupported_encoding">Encodage non supporté \'%s\', \'SIMPLE\' est utilisé.</string> <string name="select_encoding_warning">\'EXTENDED\' est un nouveau format de message qui ne fonctionne pas encore partout, mais qui a des avantages intéressants. Sélectionnez \'SIMPLE\' pour être sûr.</string> <string name="select_encoding_title">Sélectionner le codage des messages</string> @@ -125,4 +124,12 @@ <string name="select_encoding">Choix du codage</string> <string name="help_out_link">https://dissem.github.io/Abit/aider</string> <string name="from">De</string> + <string name="invalid_wif_file">Le fichier ne peut pas être traité</string> + <string name="inbox">Boîte de réception</string> + <string name="outbox">Boîte d\'envoi</string> + <string name="draft">Brouillons</string> + <string name="sent">Envoyé</string> + <string name="unread">Non lues</string> + <string name="trash">Corbeille</string> + <string name="broadcasts">Diffusions</string> </resources> diff --git a/app/src/main/res/values/labels.xml b/app/src/main/res/values/labels.xml deleted file mode 100644 index c1e7259..0000000 --- a/app/src/main/res/values/labels.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?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. - --> - -<resources> - <string name="inbox">Inbox</string> - <string name="draft">Drafts</string> - <string name="sent">Sent</string> - <string name="unread">Unread</string> - <string name="trash">Trash</string> - <string name="broadcasts">Broadcasts</string> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9d4edbb..bc041e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -108,7 +108,6 @@ As an alternative you could configure a trusted node in the settings, but as of <string name="status_draft">draft</string> <string name="status_sent">sent</string> <string name="status_received">received</string> - <string name="outbox">Outbox</string> <string name="error_unsupported_encoding">Unsupported encoding ‘%s’, using ‘SIMPLE’ instead.</string> <string name="select_encoding_warning">‘EXTENDED’ is a new message format that\'s not widely supported yet but has some interesting features. To stay on the save side, select ‘SIMPLE’.</string> <string name="select_encoding_title">Select Message Encoding</string> @@ -127,4 +126,12 @@ As an alternative you could configure a trusted node in the settings, but as of <string name="got_it">Got it</string> <string name="select_encoding">Select encoding</string> <string name="from">From</string> + <string name="invalid_wif_file">The file could not be processed</string> + <string name="inbox">Inbox</string> + <string name="outbox">Outbox</string> + <string name="draft">Drafts</string> + <string name="sent">Sent</string> + <string name="unread">Unread</string> + <string name="trash">Trash</string> + <string name="broadcasts">Broadcasts</string> </resources> From 9e59187ae0f386cb7e97e46c6ae892aabfff2bc8 Mon Sep 17 00:00:00 2001 From: Christian Basler <chrigu.meyer@gmail.com> Date: Wed, 21 Feb 2018 15:05:38 +0100 Subject: [PATCH 15/20] Handle invalid WIF files --- .../apps/abit/ImportIdentitiesFragment.kt | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) 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 5cbdf4e..29a4fce 100644 --- a/app/src/main/java/ch/dissem/apps/abit/ImportIdentitiesFragment.kt +++ b/app/src/main/java/ch/dissem/apps/abit/ImportIdentitiesFragment.kt @@ -25,12 +25,12 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button - -import com.h6ah4i.android.widget.advrecyclerview.decoration.SimpleListDividerDecorator - import ch.dissem.apps.abit.adapter.AddressSelectorAdapter import ch.dissem.apps.abit.service.Singleton import ch.dissem.bitmessage.wif.WifImporter +import com.h6ah4i.android.widget.advrecyclerview.decoration.SimpleListDividerDecorator +import org.ini4j.InvalidFileFormatException +import org.jetbrains.anko.longToast /** * @author Christian Basler @@ -39,8 +39,12 @@ class ImportIdentitiesFragment : Fragment() { private lateinit var adapter: AddressSelectorAdapter private lateinit var importer: WifImporter - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = - inflater.inflate(R.layout.fragment_import_select_identities, container, false) + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View = + inflater.inflate(R.layout.fragment_import_select_identities, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -48,17 +52,29 @@ class ImportIdentitiesFragment : Fragment() { val wifData = arguments.getString(WIF_DATA) val bmc = Singleton.getBitmessageContext(activity) - importer = WifImporter(bmc, wifData) + try { + importer = WifImporter(bmc, wifData) + } catch (e: InvalidFileFormatException) { + longToast(R.string.invalid_wif_file) + activity.finish() + return; + } + adapter = AddressSelectorAdapter(importer.getIdentities()) - val layoutManager = LinearLayoutManager(activity, - LinearLayoutManager.VERTICAL, - false) + val layoutManager = LinearLayoutManager( + activity, + LinearLayoutManager.VERTICAL, + false + ) val recyclerView = view.findViewById<RecyclerView>(R.id.recycler_view) recyclerView.layoutManager = layoutManager recyclerView.adapter = adapter - recyclerView.addItemDecoration(SimpleListDividerDecorator( - ContextCompat.getDrawable(activity, R.drawable.list_divider_h), true)) + recyclerView.addItemDecoration( + SimpleListDividerDecorator( + ContextCompat.getDrawable(activity, R.drawable.list_divider_h), true + ) + ) view.findViewById<Button>(R.id.finish).setOnClickListener { importer.importAll(adapter.selected) From 3509082d30991a4aa41ae40dd38631355fff0411 Mon Sep 17 00:00:00 2001 From: Christian Basler <chrigu.meyer@gmail.com> Date: Wed, 21 Feb 2018 16:55:22 +0100 Subject: [PATCH 16/20] Remove redundant semicolon; --- .../main/java/ch/dissem/apps/abit/ImportIdentitiesFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 29a4fce..fdce2b8 100644 --- a/app/src/main/java/ch/dissem/apps/abit/ImportIdentitiesFragment.kt +++ b/app/src/main/java/ch/dissem/apps/abit/ImportIdentitiesFragment.kt @@ -57,7 +57,7 @@ class ImportIdentitiesFragment : Fragment() { } catch (e: InvalidFileFormatException) { longToast(R.string.invalid_wif_file) activity.finish() - return; + return } adapter = AddressSelectorAdapter(importer.getIdentities()) From b4b1d25f9902262d2d549a7b62c8563a859f8dcd Mon Sep 17 00:00:00 2001 From: NourEddine <noureddine1x1@gmail.com> Date: Wed, 21 Feb 2018 23:17:19 +0000 Subject: [PATCH 17/20] Translated using Weblate (Arabic) Currently translated at 100.0% (132 of 132 strings) Translation: Abit/App Translate-URL: http://translations.dissem.ch/projects/abit/app/ar/ --- app/src/main/res/values-ar/strings.xml | 97 ++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 986d7f2..36da7e9 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -15,8 +15,8 @@ <string name="manage_identity">إدارة الهويات</string> <string name="add_identity">إضافة هوية</string> <string name="add_identity_summary">إنشاء هوية جديدة</string> - <string name="create_identity_description">إنشاء هوية جديدة عشوائية</string> - <string name="import_identity_description">إستيراد هوية موجودة من PyBitmessage او من تصدير</string> + <string name="create_identity_description">إنشاء هوية عشوائية جديدة</string> + <string name="import_identity_description">استيراد هوية موجودة من PyBitmessage او من تصدير</string> <string name="add_deterministic_address">هوية حتمية</string> <string name="add_deterministic_address_description">إنشاء أو إعادة إنشاء هوية حتمية</string> <string name="add_chan">إضافة قناة</string> @@ -34,15 +34,102 @@ <string name="trusted_node_summary">استخدام العقدة في التزامن</string> <string name="write_message">كتابة رسالة</string> <string name="full_node">عقدة كاملة</string> - <string name="send">أرسل</string> + <string name="send">إرسال</string> <string name="connection_info_disconnected">غير متصل</string> <string name="connection_info_pending">يتصل…</string> <string name="proof_of_work_title">إثبات العمل</string> <string name="proof_of_work_text_0">جاري إثبات العمل لإرسال الرسالة</string> - <string name="inbox">علبة الوارد</string> + <string name="inbox">صندوق الوارد</string> <string name="draft">مسودات</string> - <string name="sent">تاريخ الإرسال</string> + <string name="sent">المرسل</string> <string name="unread">غير مقروء</string> <string name="trash">مُهملات</string> <string name="label">تسمية</string> +<string name="connection_info_1">بث #%1$d : توصيل واحد</string> + <string name="connection_info_n" tools:ignore="PluralsCandidate">"بث #%1$d: %2$d توصيلات"</string> + <string name="broadcast">إذاعة</string> + <string name="mark_unread">حدد كمقروء</string> + <string name="archive">أرشيف</string> + <string name="stream_number">بث #%d</string> + <string name="sync_timeout">انتهاء مهلة التزامن</string> + <string name="sync_timeout_summary">مهلة الإتصال بالثواني</string> + <string name="proof_of_work_text_n" tools:ignore="PluralsCandidate">جاري إثبات العمل لإرسال الرسالة (%1$d في قائمة الانتظار)</string> + <string name="error_invalid_sync_port">إعدادات منفذ التزامن غير صالحة</string> + <string name="compose_body_hint">كتابة رسالة</string> + <string name="contacts_and_subscriptions">جهات اتصال</string> + <string name="subscribed">تم الاشتراك</string> + <string name="server_pow">خادم إثبات العمل</string> + <string name="server_pow_summary">عقدة موثوقة تقوم بإثبات العمل</string> + <string name="full_node_warning">تشغيل عقدة Bitmessage كاملة يستهلك الكثير من البيانات، مما قد يكون مكلفًا لبيانات الهاتف، هل أنت متأكد أنك تريد تشغيل عقدة كاملة؟</string> + <string name="about">عن Abit</string> + <string name="about_summary">التبعيات مفتوحة المصدر.</string> + <string name="title_activity_status">تصحيح الأخطاء</string> + <string name="status">تصحيح الأخطاء</string> + <string name="status_summary">معلومات تقنية</string> + <string name="alias_default_identity">أنا</string> + <string name="pubkey_available">مفتاح التشفير المعلن متاح</string> + <string name="pubkey_not_available">مفتاح التشفير المعلن غير متاح بعد</string> + <string name="alt_qr_code">شفرة QR</string> + <string name="add_identity_warning">حيازة عدة هويات يحتاج إلى المزيد من الموارد، إذا كنت متأكدًأ أنك تريد إضافة هويات، أختر تمامًا ما تريد عمله:</string> + <string name="share">نشر</string> + <string name="delete_identity_warning">هل أنت متأكد من أنك تريد حذف هذه الهوية؟ لن تستطيع استقبال أي رسائل مرسلة لهذا العنوان ولا يمكنك التراجع عن هذه العملية.</string> + <string name="delete_contact_warning">هل أنت متأكد أنك تريد حذف جهة الاتصال هذه؟</string> + <string name="scan_qr_code">مسح شفرة QR</string> + <string name="create_contact">إنشاء جهة إتصال</string> + <string name="full_node_description">لا يمكنك إرسال أو استقبال رسائل إلا إذا قمت بتشغيل عقدة كاملة. رجاء العلم أن ذلك يستخدم الكثير من الموارد وبيانات الإنترنت. يمكنك تعيين عقدة موثوقة في الإعدادات، ويمكنك إطلاق عقدتك الخاصة.</string> + <string name="address">عنوان Bitmessage</string> + <string name="error_illegal_address">قد يكون هناك خطأ بالكتابة</string> + <string name="export">تصدير</string> + <string name="confirm_export">هل أنت متأكد أنك تريد تصدير هويتك؟ سيحتوي التصدير على مفاتيح خاصة غير مشفرة.</string> + <string name="compose_message">إنشاء</string> + <string name="passphrase">جملة المرور</string> + <string name="help_out">ادعم التطوير</string> + <string name="help_out_summary">هل تريد المساعدة؟ ألق نظرة هنا</string> + <string name="help_out_link">https://dissem.github.io/Abit/helping-out</string> + <string name="toast_long_running_operation">قد يستغرق بضع دقائق</string> + <string name="toast_identity_created">تم إنشاء الهوية</string> + <string name="toast_identities_created">تم إنشاء الهويات</string> + <string name="toast_chan_created">تم إنشاء القناة</string> + <string name="deterministic_address_warning">تأكد من تذكر هذه الإعدادات جيدًا عندما تعيد إنشاء الهوية الختمية.</string> + <string name="number_of_identities">عدد الهويات المنشئة</string> + <string name="shorter">ابحث عن عنوان أقصر</string> + <string name="wif_string">محتويات keys.dat</string> + <string name="next">استمرار</string> + <string name="title_import_identity">استيراد هوية</string> + <string name="open_file">فتح ملف</string> + <string name="error_loading_data">خطأ في تحميل البيانات</string> + <string name="select_file_title">اختيار ملف</string> + <string name="select_identities_to_import">اختر الهويات التي تريد استيرادها:</string> + <string name="import_input_description">يمكنك لصق محتويات تصدير او ملف keys.dat</string> + <string name="full_node_stop">إيقاف العقدة</string> + <string name="full_node_restart">اعادة تشغيل العقدة</string> + <string name="use_mobile_network">استخدم شبكة بيانات الهاتف</string> + <string name="personal_message">رسالة</string> + <string name="no_identity_warning">أعد المحاولة عند وجود هوية متاحة.</string> + <string name="status_public_key">تم طلب المفتاح المعلن</string> + <string name="status_sent_acknowledged">تم تسليم الرسالة</string> + <string name="status_draft">مسودة</string> + <string name="status_sent">تم الارسال</string> + <string name="status_received">تم الاستقبال</string> + <string name="error_unsupported_encoding">ترميز غير مدعوم، استخدم الترميز البسيط.</string> + <string name="select_encoding_warning">الترميز الموسع هو نظام رسالة جديد غير منتشر الدعم بعد، لكن يحتوي مميزات مختلفة. للبقاء على النظام الأكثر انتشارًا، اختر الترميز البسيط.</string> + <string name="select_encoding_title">اختر ترميز الرسالة</string> + <string name="cleanup">تطهير</string> + <string name="cleanup_summary">حذف المدخلات المنتهية</string> + <string name="cleanup_notification_start">تم بدأ التنظيف</string> + <string name="cleanup_notification_end">تم الانتهاء من التنظيف</string> + <string name="wait_for_wifi">انتظر Wi-Fi</string> + <string name="error_msg_recipient_missing">حدد المرسل إليه</string> + <string name="export_data">تصدير</string> + <string name="export_data_summary">تصدير جميع الرسائل وجهات الاتصال (الهويات غير مضمنة)</string> + <string name="import_data">استيراد</string> + <string name="import_data_summary">استيراد الرسائل وجهات الاتصال (الهويات غير مضمنة)</string> + <string name="request_acknowledgements">اطلب التبليغ بوصول الرسائل</string> + <string name="request_acknowledgements_summary">التبليغ يسمح بالتأكد من وصول الرسالة، لكن يحتاج المزيد من الوقت</string> + <string name="got_it">موافق</string> + <string name="select_encoding">اختيار الترميز</string> + <string name="from">من</string> + <string name="invalid_wif_file">لم يتم معالجة الملف</string> + <string name="outbox">صندوق المرسل</string> + <string name="broadcasts">الإذاعات</string> </resources> From 938bfc206e9961f0d3cfcd151bd5b23394a84a60 Mon Sep 17 00:00:00 2001 From: NourEddine <noureddine1x1@gmail.com> Date: Thu, 22 Feb 2018 15:45:11 +0000 Subject: [PATCH 18/20] Translated using Weblate (Arabic) Currently translated at 100.0% (132 of 132 strings) Translation: Abit/App Translate-URL: http://translations.dissem.ch/projects/abit/app/ar/ --- app/src/main/res/values-ar/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 36da7e9..7ea90b4 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -126,7 +126,7 @@ <string name="import_data_summary">استيراد الرسائل وجهات الاتصال (الهويات غير مضمنة)</string> <string name="request_acknowledgements">اطلب التبليغ بوصول الرسائل</string> <string name="request_acknowledgements_summary">التبليغ يسمح بالتأكد من وصول الرسالة، لكن يحتاج المزيد من الوقت</string> - <string name="got_it">موافق</string> + <string name="got_it">فهمت</string> <string name="select_encoding">اختيار الترميز</string> <string name="from">من</string> <string name="invalid_wif_file">لم يتم معالجة الملف</string> From fb72356467a2a9daced445cbf687df90b6e8318f Mon Sep 17 00:00:00 2001 From: Christian Basler <chrigu.meyer@gmail.com> Date: Sat, 24 Feb 2018 07:39:06 +0100 Subject: [PATCH 19/20] Retain content of compose view on orientation change --- .../apps/abit/ComposeMessageActivity.kt | 38 ++++++++++++------- .../apps/abit/ComposeMessageFragment.kt | 9 +++++ .../apps/abit/adapter/ContactAdapter.kt | 9 +++++ 3 files changed, 42 insertions(+), 14 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 618504a..ea9828c 100644 --- a/app/src/main/java/ch/dissem/apps/abit/ComposeMessageActivity.kt +++ b/app/src/main/java/ch/dissem/apps/abit/ComposeMessageActivity.kt @@ -43,13 +43,15 @@ class ComposeMessageActivity : AppCompatActivity() { setHomeButtonEnabled(false) } - // Display the fragment as the main content. - val fragment = ComposeMessageFragment() - fragment.arguments = intent.extras - supportFragmentManager - .beginTransaction() - .replace(R.id.content, fragment) - .commit() + if (supportFragmentManager.findFragmentById(R.id.content) == null) { + // Display the fragment as the main content. + val fragment = ComposeMessageFragment() + fragment.arguments = intent.extras + supportFragmentManager + .beginTransaction() + .replace(R.id.content, fragment) + .commit() + } } companion object { @@ -63,10 +65,13 @@ class ComposeMessageActivity : AppCompatActivity() { const val EXTRA_PARENT = "ch.dissem.abit.Message.PARENT" fun launchReplyTo(fragment: Fragment, item: Plaintext) = - fragment.startActivity(getReplyIntent( - ctx = fragment.activity ?: throw IllegalStateException("Fragment not attached to an activity"), - item = item - )) + fragment.startActivity( + getReplyIntent( + ctx = fragment.activity + ?: throw IllegalStateException("Fragment not attached to an activity"), + item = item + ) + ) fun launchReplyTo(activity: Activity, item: Plaintext) = activity.startActivity(getReplyIntent(activity, item)) @@ -90,15 +95,20 @@ class ComposeMessageActivity : AppCompatActivity() { } replyIntent.putExtra(EXTRA_PARENT, item) item.subject?.let { subject -> - val prefix: String = if (subject.length >= 3 && subject.substring(0, 3).equals("RE:", ignoreCase = true)) { + val prefix: String = if (subject.length >= 3 && subject.substring(0, 3).equals( + "RE:", + ignoreCase = true + )) { "" } else { "RE: " } replyIntent.putExtra(EXTRA_SUBJECT, prefix + subject) } - replyIntent.putExtra(EXTRA_CONTENT, - "\n\n------------------------------------------------------\n" + item.text!!) + replyIntent.putExtra( + EXTRA_CONTENT, + "\n\n------------------------------------------------------\n" + item.text!! + ) return replyIntent } } 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 c248aef..dce64fa 100644 --- a/app/src/main/java/ch/dissem/apps/abit/ComposeMessageFragment.kt +++ b/app/src/main/java/ch/dissem/apps/abit/ComposeMessageFragment.kt @@ -63,6 +63,7 @@ class ComposeMessageFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + retainInstance = true arguments?.apply { val draft = getSerializable(EXTRA_DRAFT) as Plaintext? if (draft != null) { @@ -266,6 +267,14 @@ class ComposeMessageFragment : Fragment() { super.onPause() } + override fun onDestroyView() { + identity = sender_input.selectedItem as BitmessageAddress + // recipient is set when one is selected + subject = subject_input.text?.toString() ?: "" + content = body_input.text?.toString() ?: "" + super.onDestroyView() + } + private fun send() { val ctx = activity ?: throw IllegalStateException("Fragment is not attached to an activity") if (recipient == null) { 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 c32e44d..8aa73f4 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 @@ -114,6 +114,13 @@ class ContactAdapter( }.invoke() } + if (newValues.isEmpty()) { + try { + newValues.add(BitmessageAddress(prefix.toString())) + } catch (_: Exception) { + } + } + results.values = newValues results.count = newValues.size } else { @@ -134,4 +141,6 @@ class ContactAdapter( } } } + + fun indexOf(element: BitmessageAddress) = originalData.indexOf(element) } From ab70e6df12ab80cfc5df455ec8ff399251693a68 Mon Sep 17 00:00:00 2001 From: Christian Basler <chrigu.meyer@gmail.com> Date: Sat, 24 Feb 2018 08:49:05 +0100 Subject: [PATCH 20/20] Version 1.0-rc1 bump --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 4495a2c..0289097 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ android { applicationId "ch.dissem.apps.${appName.toLowerCase()}" minSdkVersion 19 targetSdkVersion 27 - versionCode 20 - versionName "1.0-beta20" + versionCode 22 + versionName "1.0-rc1" multiDexEnabled true } compileOptions {