diff --git a/app/build.gradle b/app/build.gradle index 72bea9f..7d4133e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -51,9 +51,10 @@ android { //ext.jabitVersion = '2.0.4' ext.jabitVersion = 'feature-refactoring-SNAPSHOT' -ext.supportVersion = '27.0.1' +ext.supportVersion = '27.0.2' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" implementation "org.jetbrains.anko:anko:$anko_version" @@ -74,22 +75,22 @@ dependencies { implementation 'org.slf4j:slf4j-android:1.7.25' - implementation 'com.mikepenz:materialize:1.1.0@aar' - implementation('com.mikepenz:materialdrawer:5.9.5@aar') { + implementation 'com.mikepenz:materialize:1.1.2@aar' + implementation('com.mikepenz:materialdrawer:6.0.2@aar') { transitive = true } - implementation('com.mikepenz:aboutlibraries:5.9.7@aar') { + implementation('com.mikepenz:aboutlibraries:6.0.1@aar') { transitive = true } - implementation "com.mikepenz:iconics-core:2.9.3@aar" - implementation "com.mikepenz:iconics-views:2.9.3@aar" - implementation 'com.mikepenz:google-material-typeface:3.0.1.1.original@aar' - implementation 'com.mikepenz:community-material-typeface:1.9.32.2@aar' + implementation "com.mikepenz:iconics-core:3.0.0@aar" + implementation "com.mikepenz:iconics-views:3.0.0@aar" + implementation 'com.mikepenz:google-material-typeface:3.0.1.2.original@aar' + implementation 'com.mikepenz:community-material-typeface:2.0.46.1@aar' implementation 'com.journeyapps:zxing-android-embedded:3.5.0@aar' implementation 'com.google.zxing:core:3.3.1' - implementation 'com.github.kobakei:MaterialFabSpeedDial:1.1.7' + implementation 'com.github.kobakei:MaterialFabSpeedDial:1.1.8' implementation 'com.github.amlcurran.showcaseview:library:5.4.3' implementation('com.github.h6ah4i:android-advancedrecyclerview:0.11.0@aar') { transitive = true @@ -98,12 +99,12 @@ dependencies { implementation 'com.android.support.constraint:constraint-layout:1.0.2' testImplementation 'junit:junit:4.12' - testImplementation 'org.mockito:mockito-core:2.11.0' + testImplementation 'org.mockito:mockito-core:2.13.0' testImplementation 'org.hamcrest:hamcrest-library:1.3' testImplementation 'com.nhaarman:mockito-kotlin-kt1.1:1.5.0' testImplementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - testImplementation 'org.robolectric:robolectric:3.5' - testImplementation "org.robolectric:shadows-multidex:3.5" + testImplementation 'org.robolectric:robolectric:3.6.1' + testImplementation "org.robolectric:shadows-multidex:3.6.1" androidTestImplementation "com.android.support:multidex:1.0.2" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 69c46cc..ddca7b0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,9 +4,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> - + 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 59f578f..25a3742 100644 --- a/app/src/main/java/ch/dissem/apps/abit/MainActivity.kt +++ b/app/src/main/java/ch/dissem/apps/abit/MainActivity.kt @@ -114,9 +114,9 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { val listFragment = MessageListFragment() supportFragmentManager - .beginTransaction() - .replace(R.id.item_list, listFragment) - .commit() + .beginTransaction() + .replace(R.id.item_list, listFragment) + .commit() if (findViewById(R.id.message_detail_container) != null) { // The detail container view will be present only in the @@ -149,40 +149,38 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { } if (drawer.isDrawerOpen) { val lps = RelativeLayout.LayoutParams(ViewGroup - .LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) + .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) ShowcaseView.Builder(this) - .withMaterialShowcase() - .setStyle(R.style.CustomShowcaseTheme) - .setContentTitle(R.string.full_node) - .setContentText(R.string.full_node_description) - .setTarget { - val view = drawer.stickyFooter - val location = IntArray(2) - view.getLocationInWindow(location) - val x = location[0] + 7 * view.width / 8 - val y = location[1] + view.height / 2 - Point(x, y) - } - .replaceEndButton(R.layout.showcase_button) - .hideOnTouchOutside() - .build() - .setButtonPosition(lps) + .withMaterialShowcase() + .setStyle(R.style.CustomShowcaseTheme) + .setContentTitle(R.string.full_node) + .setContentText(R.string.full_node_description) + .setTarget { + val view = drawer.stickyFooter + val location = IntArray(2) + view.getLocationInWindow(location) + val x = location[0] + 7 * view.width / 8 + val y = location[1] + view.height / 2 + Point(x, y) + } + .replaceEndButton(R.layout.showcase_button) + .hideOnTouchOutside() + .build() + .setButtonPosition(lps) } } private fun changeList(listFragment: F) where F : Fragment, F : ListHolder<*> { if (active) { - val transaction = supportFragmentManager - .beginTransaction() + val transaction = supportFragmentManager.beginTransaction() transaction.replace(R.id.item_list, listFragment) - val detailFragment = supportFragmentManager.findFragmentById(R.id.message_detail_container) - if (detailFragment != null) { - transaction.remove(detailFragment) + supportFragmentManager.findFragmentById(R.id.message_detail_container)?.let { + transaction.remove(it) } transaction.addToBackStack(null).commit() @@ -197,67 +195,67 @@ 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()) + .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()) + .withName(getString(R.string.manage_identity)) + .withIcon(GoogleMaterial.Icon.gmd_settings) + .withIdentifier(MANAGE_IDENTITY.toLong()) ) // Create the AccountHeader accountHeader = AccountHeaderBuilder() - .withActivity(this) - .withHeaderBackground(R.drawable.header) - .withProfiles(profiles) - .withOnAccountHeaderProfileImageListener(ProfileImageListener(this)) - .withOnAccountHeaderListener(ProfileSelectionListener(this@MainActivity, supportFragmentManager)) - .build() + .withActivity(this) + .withHeaderBackground(R.drawable.header) + .withProfiles(profiles) + .withOnAccountHeaderProfileImageListener(ProfileImageListener(this)) + .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() - .withName(R.string.archive) - .withTag(LABEL_ARCHIVE) - .withIcon(CommunityMaterial.Icon.cmd_archive) + .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)) + .withName(R.string.contacts_and_subscriptions) + .withIcon(GoogleMaterial.Icon.gmd_contacts)) drawerItems.add(PrimaryDrawerItem() - .withName(R.string.settings) - .withIcon(GoogleMaterial.Icon.gmd_settings)) + .withName(R.string.settings) + .withIcon(GoogleMaterial.Icon.gmd_settings)) nodeSwitch = SwitchDrawerItem() - .withIdentifier(ID_NODE_SWITCH) - .withName(R.string.full_node) - .withIcon(CommunityMaterial.Icon.cmd_cloud_outline) - .withChecked(Preferences.isFullNodeActive(this)) - .withOnCheckedChangeListener { _, _, isChecked -> - if (isChecked) { - NetworkUtils.enableNode(this@MainActivity) - } else { - NetworkUtils.disableNode(this@MainActivity) - } + .withIdentifier(ID_NODE_SWITCH) + .withName(R.string.full_node) + .withIcon(CommunityMaterial.Icon.cmd_cloud_outline) + .withChecked(Preferences.isFullNodeActive(this)) + .withOnCheckedChangeListener { _, _, isChecked -> + if (isChecked) { + NetworkUtils.enableNode(this@MainActivity) + } else { + NetworkUtils.disableNode(this@MainActivity) } + } drawer = DrawerBuilder() - .withActivity(this) - .withToolbar(toolbar) - .withAccountHeader(accountHeader) - .withDrawerItems(drawerItems) - .addStickyDrawerItems(nodeSwitch) - .withOnDrawerItemClickListener(DrawerItemClickListener()) - .withShowDrawerOnFirstLaunch(true) - .build() + .withActivity(this) + .withToolbar(toolbar) + .withAccountHeader(accountHeader) + .withDrawerItems(drawerItems) + .addStickyDrawerItems(nodeSwitch) + .withOnDrawerItemClickListener(DrawerItemClickListener()) + .withShowDrawerOnFirstLaunch(true) + .build() loadDrawerItemsAsynchronously() } @@ -289,10 +287,8 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { for (label in labels) { addLabelEntry(label) } - val selectedDrawerItem = drawer.getDrawerItem(selectedLabel) - if (selectedDrawerItem != null) { - drawer.setSelection(selectedDrawerItem) - } + drawer.setSelection(selectedLabel?.id as Long) + updateUnread() } } } @@ -338,10 +334,10 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { } R.string.settings -> { supportFragmentManager - .beginTransaction() - .replace(R.id.item_list, SettingsFragment()) - .addToBackStack(null) - .commit() + .beginTransaction() + .replace(R.id.item_list, SettingsFragment()) + .addToBackStack(null) + .commit() return false } R.string.full_node -> return true @@ -385,16 +381,16 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { fun addIdentityEntry(identity: BitmessageAddress) { val newProfile = ProfileDrawerItem() - .withIcon(Identicon(identity)) - .withName(identity.toString()) - .withNameShown(true) - .withEmail(identity.address) - .withTag(identity) + .withIcon(Identicon(identity)) + .withName(identity.toString()) + .withNameShown(true) + .withEmail(identity.address) + .withTag(identity) if (accountHeader.profiles != null) { // 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) } @@ -402,10 +398,11 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { private fun addLabelEntry(label: Label) { val item = PrimaryDrawerItem() - .withName(label.toString()) - .withTag(label) - .withIcon(Labels.getIcon(label)) - .withIconColor(Labels.getColor(label)) + .withIdentifier(label.id as Long) + .withName(label.toString()) + .withTag(label) + .withIcon(Labels.getIcon(label)) + .withIconColor(Labels.getColor(label)) drawer.addItemAtPosition(item, drawer.drawerItems.size - 3) } @@ -414,8 +411,8 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { if (profile is ProfileDrawerItem) { if (identity == profile.tag) { profile - .withName(identity.toString()) - .withTag(identity) + .withName(identity.toString()) + .withTag(identity) return } } @@ -468,8 +465,8 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { } fragment.arguments = arguments supportFragmentManager.beginTransaction() - .replace(R.id.message_detail_container, fragment) - .commit() + .replace(R.id.message_detail_container, fragment) + .commit() } else { // In single-pane mode, simply start the detail activity // for the selected item ID. @@ -490,8 +487,8 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { fun setDetailView(fragment: Fragment) { if (hasDetailPane) { supportFragmentManager.beginTransaction() - .replace(R.id.message_detail_container, fragment) - .commit() + .replace(R.id.message_detail_container, fragment) + .commit() } } @@ -513,10 +510,9 @@ class MainActivity : AppCompatActivity(), ListSelectionListener { private var instance: WeakReference? = null fun updateNodeSwitch() { - val i = getInstance() - i?.apply { + getInstance()?.apply { runOnUiThread { - nodeSwitch.withChecked(Preferences.isFullNodeActive(i)) + nodeSwitch.withChecked(Preferences.isFullNodeActive(this)) drawer.updateStickyFooterItem(nodeSwitch) } } 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 f5d4054..fb8be4d 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 @@ -120,31 +120,31 @@ class AndroidAddressRepository(private val sql: SqlHelper) : AddressRepository { private fun getAddress(c: Cursor): BitmessageAddress { - val privateKeyBytes = c.getBlob(c.getColumnIndex(COLUMN_PRIVATE_KEY)) - val address = privateKeyBytes?.let { - BitmessageAddress(PrivateKey.read(ByteArrayInputStream(privateKeyBytes))) - } ?: - BitmessageAddress(c.getString(c.getColumnIndex(COLUMN_ADDRESS))).also { address -> - c.getBlob(c.getColumnIndex(COLUMN_PUBLIC_KEY))?.let { publicKeyBytes -> - Factory.readPubkey( - version = address.version, stream = address.stream, - input = ByteArrayInputStream(publicKeyBytes), length = publicKeyBytes.size, - encrypted = false - ).let { - address.pubkey = if (address.version == 4L && it is V3Pubkey) { - V4Pubkey(it) - } else { - it - } + fun getIdentity(c: Cursor) = c.getBlob(c.getColumnIndex(COLUMN_PRIVATE_KEY))?.let { + BitmessageAddress(PrivateKey.read(ByteArrayInputStream(it))) + } + + fun getContact(c: Cursor) = BitmessageAddress(c.getString(c.getColumnIndex(COLUMN_ADDRESS))).also { address -> + c.getBlob(c.getColumnIndex(COLUMN_PUBLIC_KEY))?.let { publicKeyBytes -> + Factory.readPubkey( + version = address.version, stream = address.stream, + input = ByteArrayInputStream(publicKeyBytes), length = publicKeyBytes.size, + encrypted = false + ).let { + address.pubkey = if (address.version == 4L && it is V3Pubkey) { + V4Pubkey(it) + } else { + it } } } + } - address.alias = c.getString(c.getColumnIndex(COLUMN_ALIAS)) - address.isChan = c.getInt(c.getColumnIndex(COLUMN_CHAN)) == 1 - address.isSubscribed = c.getInt(c.getColumnIndex(COLUMN_SUBSCRIBED)) == 1 - - return address + return (getIdentity(c) ?: getContact(c)).apply { + alias = c.getString(c.getColumnIndex(COLUMN_ALIAS)) + isChan = c.getInt(c.getColumnIndex(COLUMN_CHAN)) == 1 + isSubscribed = c.getInt(c.getColumnIndex(COLUMN_SUBSCRIBED)) == 1 + } } override fun save(address: BitmessageAddress) = if (exists(address)) { diff --git a/app/src/main/java/ch/dissem/apps/abit/util/Preferences.kt b/app/src/main/java/ch/dissem/apps/abit/util/Preferences.kt index 47407b2..b8b571f 100644 --- a/app/src/main/java/ch/dissem/apps/abit/util/Preferences.kt +++ b/app/src/main/java/ch/dissem/apps/abit/util/Preferences.kt @@ -88,7 +88,7 @@ object Preferences { return preferences.getString(name, null) } - fun isConnectionAllowed(ctx: Context) = !isWifiOnly(ctx) || ctx.connectivityManager.isActiveNetworkMetered + fun isConnectionAllowed(ctx: Context) = !isWifiOnly(ctx) || !ctx.connectivityManager.isActiveNetworkMetered fun isWifiOnly(ctx: Context): Boolean { val preferences = PreferenceManager.getDefaultSharedPreferences(ctx) diff --git a/build.gradle b/build.gradle index acf0e7c..fe5bf6a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ buildscript { - ext.kotlin_version = '1.1.61' - ext.anko_version = '0.10.2' + ext.kotlin_version = '1.2.10' + ext.anko_version = '0.10.4' repositories { jcenter() google()