🤯 Update dependencies, switch to AndroidX
This commit is contained in:
parent
e67a4ea71b
commit
0405d9e04f
@ -13,8 +13,8 @@ if (project.hasProperty("project.configs")
|
|||||||
|
|
||||||
//noinspection GroovyMissingReturnStatement
|
//noinspection GroovyMissingReturnStatement
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion 28
|
||||||
buildToolsVersion "27.0.3"
|
buildToolsVersion "28.0.3"
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
release
|
release
|
||||||
@ -22,7 +22,7 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "ch.dissem.apps.${appName.toLowerCase()}"
|
applicationId "ch.dissem.apps.${appName.toLowerCase()}"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 27
|
targetSdkVersion 28
|
||||||
versionCode 23
|
versionCode 23
|
||||||
versionName "1.0-rc1"
|
versionName "1.0-rc1"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
@ -62,13 +62,16 @@ dependencies {
|
|||||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||||
implementation "org.jetbrains.anko:anko:$anko_version"
|
implementation "org.jetbrains.anko:anko:$anko_version"
|
||||||
|
|
||||||
implementation "com.android.support:appcompat-v7:$supportVersion"
|
implementation 'androidx.appcompat:appcompat:1.0.0'
|
||||||
implementation "com.android.support:preference-v7:$supportVersion"
|
implementation 'androidx.preference:preference:1.0.0'
|
||||||
implementation "com.android.support:cardview-v7:$supportVersion"
|
implementation 'androidx.cardview:cardview:1.0.0'
|
||||||
implementation "com.android.support:support-v13:$supportVersion"
|
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
|
||||||
implementation "com.android.support:preference-v14:$supportVersion"
|
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
|
||||||
implementation "com.android.support:design:$supportVersion"
|
implementation 'com.google.android.material:material:1.0.0'
|
||||||
implementation "com.android.support:multidex:1.0.3"
|
implementation 'androidx.multidex:multidex:2.0.0'
|
||||||
|
implementation 'androidx.core:core-ktx:1.0.0'
|
||||||
|
implementation 'androidx.sqlite:sqlite-ktx:2.0.0-rc01'
|
||||||
|
implementation 'androidx.fragment:fragment-ktx:1.0.0'
|
||||||
|
|
||||||
implementation "ch.dissem.jabit:jabit-core:$jabitVersion"
|
implementation "ch.dissem.jabit:jabit-core:$jabitVersion"
|
||||||
implementation "ch.dissem.jabit:jabit-networking:$jabitVersion"
|
implementation "ch.dissem.jabit:jabit-networking:$jabitVersion"
|
||||||
@ -80,15 +83,15 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'org.slf4j:slf4j-android:1.7.25'
|
implementation 'org.slf4j:slf4j-android:1.7.25'
|
||||||
|
|
||||||
implementation 'com.mikepenz:materialize:1.1.2@aar'
|
implementation 'com.mikepenz:materialize:1.2.0-rc01@aar'
|
||||||
implementation('com.mikepenz:materialdrawer:6.0.8@aar') {
|
implementation('com.mikepenz:materialdrawer:6.1.0-rc01.2@aar') {
|
||||||
transitive = true
|
transitive = true
|
||||||
}
|
}
|
||||||
implementation('com.mikepenz:aboutlibraries:6.0.9@aar') {
|
implementation('com.mikepenz:aboutlibraries:6.2.0-rc01@aar') {
|
||||||
transitive = true
|
transitive = true
|
||||||
}
|
}
|
||||||
implementation "com.mikepenz:iconics-core:3.0.4@aar"
|
implementation "com.mikepenz:iconics-core:3.1.0-rc01@aar"
|
||||||
implementation "com.mikepenz:iconics-views:3.0.4@aar"
|
implementation "com.mikepenz:iconics-views:3.1.0-rc01@aar"
|
||||||
implementation 'com.mikepenz:google-material-typeface:3.0.1.2.original@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.mikepenz:community-material-typeface:2.0.46.1@aar'
|
||||||
|
|
||||||
@ -97,11 +100,12 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'com.github.kobakei:MaterialFabSpeedDial:1.2.0'
|
implementation 'com.github.kobakei:MaterialFabSpeedDial:1.2.0'
|
||||||
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0@aar'
|
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0@aar'
|
||||||
implementation('com.github.h6ah4i:android-advancedrecyclerview:0.11.0@aar') {
|
|
||||||
transitive = true
|
|
||||||
}
|
|
||||||
implementation 'com.github.angads25:filepicker:1.1.1'
|
implementation 'com.github.angads25:filepicker:1.1.1'
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2'
|
||||||
|
|
||||||
|
implementation "io.reactivex.rxjava2:rxjava:2.2.2"
|
||||||
|
implementation "io.reactivex.rxjava2:rxkotlin:2.3.0"
|
||||||
|
implementation "io.reactivex.rxjava2:rxandroid:2.1.0"
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
testImplementation 'org.mockito:mockito-core:2.19.0'
|
testImplementation 'org.mockito:mockito-core:2.19.0'
|
||||||
@ -111,7 +115,7 @@ dependencies {
|
|||||||
testImplementation 'org.robolectric:robolectric:3.7.1'
|
testImplementation 'org.robolectric:robolectric:3.7.1'
|
||||||
testImplementation "org.robolectric:shadows-multidex:3.7.1"
|
testImplementation "org.robolectric:shadows-multidex:3.7.1"
|
||||||
|
|
||||||
androidTestImplementation "com.android.support:multidex:1.0.3"
|
androidTestImplementation "androidx.multidex:multidex:2.0.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
idea.module {
|
idea.module {
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
|
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
|
||||||
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
|
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
|
||||||
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="android.support.multidex.MultiDexApplication"
|
android:name="androidx.multidex.MultiDexApplication"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
@ -124,7 +125,7 @@
|
|||||||
|
|
||||||
<!-- Exports -->
|
<!-- Exports -->
|
||||||
<provider
|
<provider
|
||||||
android:name="android.support.v4.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="ch.dissem.apps.abit.fileprovider"
|
android:authorities="ch.dissem.apps.abit.fileprovider"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:grantUriPermissions="true">
|
android:grantUriPermissions="true">
|
||||||
|
@ -18,7 +18,7 @@ package ch.dissem.apps.abit
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.ListFragment
|
import androidx.fragment.app.ListFragment
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ListView
|
import android.widget.ListView
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ package ch.dissem.apps.abit
|
|||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import android.view.*
|
import android.view.*
|
||||||
|
@ -28,7 +28,6 @@ import android.widget.ImageView
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import ch.dissem.apps.abit.service.Singleton
|
import ch.dissem.apps.abit.service.Singleton
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||||
import com.google.zxing.integration.android.IntentIntegrator
|
|
||||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
||||||
import org.jetbrains.anko.doAsync
|
import org.jetbrains.anko.doAsync
|
||||||
import org.jetbrains.anko.uiThread
|
import org.jetbrains.anko.uiThread
|
||||||
@ -44,7 +43,7 @@ class AddressListFragment : AbstractItemListFragment<Void, BitmessageAddress>()
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
adapter = object : ArrayAdapter<BitmessageAddress>(
|
adapter = object : ArrayAdapter<BitmessageAddress>(
|
||||||
activity,
|
activity!!,
|
||||||
R.layout.subscription_row,
|
R.layout.subscription_row,
|
||||||
R.id.name,
|
R.id.name,
|
||||||
LinkedList()
|
LinkedList()
|
||||||
@ -109,9 +108,10 @@ class AddressListFragment : AbstractItemListFragment<Void, BitmessageAddress>()
|
|||||||
activity.initFab(R.drawable.ic_action_add_contact, menu)
|
activity.initFab(R.drawable.ic_action_add_contact, menu)
|
||||||
.addOnMenuItemClickListener { _, _, itemId ->
|
.addOnMenuItemClickListener { _, _, itemId ->
|
||||||
when (itemId) {
|
when (itemId) {
|
||||||
1 -> IntentIntegrator.forSupportFragment(this@AddressListFragment)
|
// FIXME
|
||||||
.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
|
// 1 -> IntentIntegrator.forSupportFragment(this@AddressListFragment)
|
||||||
.initiateScan()
|
// .setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
|
||||||
|
// .initiateScan()
|
||||||
2 -> {
|
2 -> {
|
||||||
val intent = Intent(getActivity(), CreateAddressActivity::class.java)
|
val intent = Intent(getActivity(), CreateAddressActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
|
@ -20,8 +20,8 @@ import android.app.Activity
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.support.v7.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import ch.dissem.apps.abit.service.Singleton
|
import ch.dissem.apps.abit.service.Singleton
|
||||||
import ch.dissem.bitmessage.entity.Plaintext
|
import ch.dissem.bitmessage.entity.Plaintext
|
||||||
import ch.dissem.bitmessage.entity.Plaintext.Encoding.EXTENDED
|
import ch.dissem.bitmessage.entity.Plaintext.Encoding.EXTENDED
|
||||||
|
@ -20,7 +20,7 @@ import android.app.Activity.RESULT_OK
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@ -89,10 +89,10 @@ class ComposeMessageFragment : Fragment() {
|
|||||||
recipient = getSerializable(EXTRA_RECIPIENT) as BitmessageAddress
|
recipient = getSerializable(EXTRA_RECIPIENT) as BitmessageAddress
|
||||||
}
|
}
|
||||||
if (containsKey(EXTRA_SUBJECT)) {
|
if (containsKey(EXTRA_SUBJECT)) {
|
||||||
subject = getString(EXTRA_SUBJECT)
|
subject = getString(EXTRA_SUBJECT) ?: throw IllegalStateException("EXTRA_SUBJECT expected")
|
||||||
}
|
}
|
||||||
if (containsKey(EXTRA_CONTENT)) {
|
if (containsKey(EXTRA_CONTENT)) {
|
||||||
content = getString(EXTRA_CONTENT)
|
content = getString(EXTRA_CONTENT) ?: throw IllegalStateException("EXTRA_CONTENT expected")
|
||||||
}
|
}
|
||||||
encoding = getSerializable(EXTRA_ENCODING) as? Plaintext.Encoding ?: Plaintext.Encoding.SIMPLE
|
encoding = getSerializable(EXTRA_ENCODING) as? Plaintext.Encoding ?: Plaintext.Encoding.SIMPLE
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
package ch.dissem.apps.abit
|
package ch.dissem.apps.abit
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import ch.dissem.apps.abit.adapter.ConversationAdapter
|
import ch.dissem.apps.abit.adapter.ConversationAdapter
|
||||||
import ch.dissem.apps.abit.service.Singleton
|
import ch.dissem.apps.abit.service.Singleton
|
||||||
@ -74,8 +74,7 @@ class ConversationDetailFragment : Fragment() {
|
|||||||
item?.let { item ->
|
item?.let { item ->
|
||||||
subject.text = item.subject
|
subject.text = item.subject
|
||||||
avatar.setImageDrawable(MultiIdenticon(item.participants))
|
avatar.setImageDrawable(MultiIdenticon(item.participants))
|
||||||
messages.adapter =
|
messages.adapter = ConversationAdapter(ctx, this@ConversationDetailFragment, item, Singleton.currentLabel)
|
||||||
ConversationAdapter(ctx, this@ConversationDetailFragment, item, Singleton.currentLabel.value)
|
|
||||||
messages.layoutManager = LinearLayoutManager(activity)
|
messages.layoutManager = LinearLayoutManager(activity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,36 +19,29 @@ package ch.dissem.apps.abit
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.Fragment
|
|
||||||
import android.support.v4.content.ContextCompat
|
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.support.v7.widget.RecyclerView.OnScrollListener
|
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
|
||||||
import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_BROADCAST
|
import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_BROADCAST
|
||||||
import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_IDENTITY
|
import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_IDENTITY
|
||||||
|
import ch.dissem.apps.abit.adapter.EventListener
|
||||||
|
import ch.dissem.apps.abit.adapter.SwipeToDeleteCallback
|
||||||
import ch.dissem.apps.abit.adapter.SwipeableConversationAdapter
|
import ch.dissem.apps.abit.adapter.SwipeableConversationAdapter
|
||||||
import ch.dissem.apps.abit.listener.ListSelectionListener
|
import ch.dissem.apps.abit.listener.ListSelectionListener
|
||||||
import ch.dissem.apps.abit.repository.AndroidMessageRepository
|
import ch.dissem.apps.abit.repository.AndroidMessageRepository
|
||||||
import ch.dissem.apps.abit.service.Singleton
|
import ch.dissem.apps.abit.service.Singleton
|
||||||
import ch.dissem.apps.abit.service.Singleton.currentLabel
|
import ch.dissem.apps.abit.service.Singleton.currentLabel
|
||||||
import ch.dissem.apps.abit.util.preferences
|
import ch.dissem.apps.abit.util.preferences
|
||||||
import ch.dissem.bitmessage.entity.Conversation
|
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||||
import ch.dissem.bitmessage.utils.ConversationService
|
import ch.dissem.bitmessage.utils.ConversationService
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.animator.SwipeDismissItemAnimator
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.decoration.SimpleListDividerDecorator
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
|
|
||||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
import kotlinx.android.synthetic.main.fragment_message_list.*
|
import kotlinx.android.synthetic.main.fragment_message_list.*
|
||||||
import org.jetbrains.anko.cancelButton
|
import org.jetbrains.anko.*
|
||||||
import org.jetbrains.anko.doAsync
|
|
||||||
import org.jetbrains.anko.support.v4.alert
|
|
||||||
import org.jetbrains.anko.support.v4.onUiThread
|
|
||||||
import org.jetbrains.anko.uiThread
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
private const val PAGE_SIZE = 15
|
private const val PAGE_SIZE = 15
|
||||||
@ -70,12 +63,9 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
|||||||
|
|
||||||
private var layoutManager: LinearLayoutManager? = null
|
private var layoutManager: LinearLayoutManager? = null
|
||||||
private var swipeableConversationAdapter: SwipeableConversationAdapter? = null
|
private var swipeableConversationAdapter: SwipeableConversationAdapter? = null
|
||||||
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
|
|
||||||
private var recyclerViewSwipeManager: RecyclerViewSwipeManager? = null
|
|
||||||
private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null
|
|
||||||
|
|
||||||
private val recyclerViewOnScrollListener = object : OnScrollListener() {
|
private val recyclerViewOnScrollListener = object : OnScrollListener() {
|
||||||
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
layoutManager?.let { layoutManager ->
|
layoutManager?.let { layoutManager ->
|
||||||
val visibleItemCount = layoutManager.childCount
|
val visibleItemCount = layoutManager.childCount
|
||||||
val totalItemCount = layoutManager.itemCount
|
val totalItemCount = layoutManager.itemCount
|
||||||
@ -98,6 +88,13 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
|||||||
private lateinit var conversationService: ConversationService
|
private lateinit var conversationService: ConversationService
|
||||||
private var activateOnItemClick: Boolean = false
|
private var activateOnItemClick: Boolean = false
|
||||||
|
|
||||||
|
private var subscription: Disposable? = null
|
||||||
|
|
||||||
|
override fun setActivateOnItemClick(activateOnItemClick: Boolean) {
|
||||||
|
swipeableConversationAdapter?.activateOnItemClick = activateOnItemClick
|
||||||
|
this.activateOnItemClick = activateOnItemClick
|
||||||
|
}
|
||||||
|
|
||||||
private val backStack = Stack<Label>()
|
private val backStack = Stack<Label>()
|
||||||
|
|
||||||
fun loadMoreItems() {
|
fun loadMoreItems() {
|
||||||
@ -112,7 +109,7 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
|||||||
)
|
)
|
||||||
conversationIds.forEach { conversationId ->
|
conversationIds.forEach { conversationId ->
|
||||||
val conversation = conversationService.getConversation(conversationId)
|
val conversation = conversationService.getConversation(conversationId)
|
||||||
onUiThread {
|
uiThread {
|
||||||
messageAdapter.add(conversation)
|
messageAdapter.add(conversation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,12 +132,12 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
|||||||
messageRepo = Singleton.getMessageRepository(activity)
|
messageRepo = Singleton.getMessageRepository(activity)
|
||||||
conversationService = Singleton.getConversationService(activity)
|
conversationService = Singleton.getConversationService(activity)
|
||||||
|
|
||||||
currentLabel.addObserver(this) { new -> doUpdateList(new) }
|
subscription = currentLabel.subscribe { new -> doUpdateList(new) }
|
||||||
doUpdateList(currentLabel.value)
|
doUpdateList(currentLabel.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
currentLabel.removeObserver(this)
|
subscription?.dispose()
|
||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +155,7 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
|||||||
// I'm not yet sure if it's a good idea in conversation views, so it's off for now
|
// I'm not yet sure if it's a good idea in conversation views, so it's off for now
|
||||||
deleteAllMenuItem?.isVisible = false
|
deleteAllMenuItem?.isVisible = false
|
||||||
|
|
||||||
mainActivity?.apply {
|
MainActivity.apply {
|
||||||
if ("archive" == label.toString()) {
|
if ("archive" == label.toString()) {
|
||||||
updateTitle(getString(R.string.archive))
|
updateTitle(getString(R.string.archive))
|
||||||
} else {
|
} else {
|
||||||
@ -181,75 +178,57 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
|||||||
|
|
||||||
val context = context ?: throw IllegalStateException("No context available")
|
val context = context ?: throw IllegalStateException("No context available")
|
||||||
|
|
||||||
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
val listener = object : EventListener {
|
||||||
|
override fun onItemDeleted(position: Int) {
|
||||||
// touch guard manager (this class is required to suppress scrolling while swipe-dismiss
|
swipeableConversationAdapter?.getItem(position)?.let { item ->
|
||||||
// animation is running)
|
|
||||||
val touchActionGuardManager = RecyclerViewTouchActionGuardManager().apply {
|
|
||||||
setInterceptVerticalScrollingWhileAnimationRunning(true)
|
|
||||||
isEnabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// swipe manager
|
|
||||||
val swipeManager = RecyclerViewSwipeManager()
|
|
||||||
|
|
||||||
//swipeableConversationAdapter
|
|
||||||
val adapter = SwipeableConversationAdapter(context).apply {
|
|
||||||
setActivateOnItemClick(activateOnItemClick)
|
|
||||||
}
|
|
||||||
adapter.eventListener = object : SwipeableConversationAdapter.EventListener {
|
|
||||||
override fun onItemDeleted(item: Conversation) {
|
|
||||||
item.messages.forEach {
|
item.messages.forEach {
|
||||||
Singleton.labeler.delete(it)
|
Singleton.labeler.delete(it)
|
||||||
messageRepo.save(it)
|
messageRepo.save(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemArchived(item: Conversation) {
|
swipeableConversationAdapter?.removeAt(position)
|
||||||
item.messages.forEach { Singleton.labeler.archive(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemViewClicked(v: View?) {
|
override fun onItemArchived(position: Int) {
|
||||||
val position = recycler_view.getChildAdapterPosition(v)
|
swipeableConversationAdapter?.getItem(position)?.let { item ->
|
||||||
adapter.setSelectedPosition(position)
|
item.messages.forEach {
|
||||||
|
Singleton.labeler.archive(it)
|
||||||
|
messageRepo.save(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
swipeableConversationAdapter?.removeAt(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemSelected(position: Int) {
|
||||||
|
swipeableConversationAdapter?.selectedPosition = position
|
||||||
if (position != RecyclerView.NO_POSITION) {
|
if (position != RecyclerView.NO_POSITION) {
|
||||||
MainActivity.apply { onItemSelected(adapter.getItem(position)) }
|
swipeableConversationAdapter?.getItem(position)?.let { item ->
|
||||||
|
MainActivity.apply { onItemSelected(item) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// wrap for swiping
|
layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
|
||||||
wrappedAdapter = swipeManager.createWrappedAdapter(adapter)
|
|
||||||
|
|
||||||
val animator = SwipeDismissItemAnimator()
|
|
||||||
|
|
||||||
// Change animations are enabled by default since support-v7-recyclerview v22.
|
|
||||||
// Disable the change animation in order to make turning back animation of swiped item
|
|
||||||
// works properly.
|
|
||||||
animator.supportsChangeAnimations = false
|
|
||||||
|
|
||||||
recycler_view.layoutManager = layoutManager
|
recycler_view.layoutManager = layoutManager
|
||||||
recycler_view.adapter = wrappedAdapter // requires *wrapped* swipeableConversationAdapter
|
swipeableConversationAdapter = SwipeableConversationAdapter(context).apply {
|
||||||
recycler_view.itemAnimator = animator
|
activateOnItemClick = this@ConversationListFragment.activateOnItemClick
|
||||||
|
eventListener = listener
|
||||||
|
}
|
||||||
|
recycler_view.adapter = swipeableConversationAdapter
|
||||||
recycler_view.addOnScrollListener(recyclerViewOnScrollListener)
|
recycler_view.addOnScrollListener(recyclerViewOnScrollListener)
|
||||||
|
|
||||||
recycler_view.addItemDecoration(
|
val dirs = when (currentLabel.value?.type) {
|
||||||
SimpleListDividerDecorator(
|
Label.Type.TRASH -> ItemTouchHelper.LEFT
|
||||||
ContextCompat.getDrawable(context, R.drawable.list_divider_h), true
|
else -> ItemTouchHelper.LEFT + ItemTouchHelper.RIGHT
|
||||||
)
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// NOTE:
|
val swipeHandler = SwipeToDeleteCallback(context, dirs, listener)
|
||||||
// The initialization order is very important! This order determines the priority of
|
|
||||||
// touch event handling.
|
|
||||||
//
|
|
||||||
// priority: TouchActionGuard > Swipe > DragAndDrop
|
|
||||||
touchActionGuardManager.attachRecyclerView(recycler_view)
|
|
||||||
swipeManager.attachRecyclerView(recycler_view)
|
|
||||||
|
|
||||||
recyclerViewTouchActionGuardManager = touchActionGuardManager
|
val itemTouchHelper = ItemTouchHelper(swipeHandler)
|
||||||
recyclerViewSwipeManager = swipeManager
|
itemTouchHelper.attachToRecyclerView(recycler_view)
|
||||||
swipeableConversationAdapter = adapter
|
|
||||||
|
|
||||||
// FIXME Singleton.updateMessageListAdapterInListener(adapter)
|
// FIXME Singleton.updateMessageListAdapterInListener(adapter)
|
||||||
}
|
}
|
||||||
@ -287,18 +266,6 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
recyclerViewSwipeManager?.release()
|
|
||||||
recyclerViewSwipeManager = null
|
|
||||||
|
|
||||||
recyclerViewTouchActionGuardManager?.release()
|
|
||||||
recyclerViewTouchActionGuardManager = null
|
|
||||||
|
|
||||||
recycler_view.itemAnimator = null
|
|
||||||
recycler_view.adapter = null
|
|
||||||
|
|
||||||
wrappedAdapter?.let { WrapperAdapterUtils.releaseAll(it) }
|
|
||||||
wrappedAdapter = null
|
|
||||||
|
|
||||||
swipeableConversationAdapter = null
|
swipeableConversationAdapter = null
|
||||||
layoutManager = null
|
layoutManager = null
|
||||||
|
|
||||||
@ -324,9 +291,10 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
|||||||
}
|
}
|
||||||
R.id.delete_all -> {
|
R.id.delete_all -> {
|
||||||
currentLabel.value?.let { label ->
|
currentLabel.value?.let { label ->
|
||||||
|
context?.apply {
|
||||||
alert(
|
alert(
|
||||||
title = R.string.delete_all_messages_in_list,
|
R.string.delete_all_messages_in_list,
|
||||||
message = R.string.delete_all_messages_in_list_ask
|
R.string.delete_all_messages_in_list_ask
|
||||||
) {
|
) {
|
||||||
positiveButton(R.string.delete) {
|
positiveButton(R.string.delete) {
|
||||||
deleteAllMessages(label)
|
deleteAllMessages(label)
|
||||||
@ -334,6 +302,7 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
|||||||
cancelButton { }
|
cancelButton { }
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
else -> return false
|
else -> return false
|
||||||
@ -351,18 +320,13 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun updateList(label: Label) {
|
override fun updateList(label: Label) {
|
||||||
currentLabel.value = label
|
currentLabel.onNext(label)
|
||||||
}
|
|
||||||
|
|
||||||
override fun setActivateOnItemClick(activateOnItemClick: Boolean) {
|
|
||||||
swipeableConversationAdapter?.setActivateOnItemClick(activateOnItemClick)
|
|
||||||
this.activateOnItemClick = activateOnItemClick
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showPreviousList() = if (backStack.isEmpty()) {
|
override fun showPreviousList() = if (backStack.isEmpty()) {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
currentLabel.value = backStack.pop()
|
currentLabel.onNext(backStack.pop())
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ package ch.dissem.apps.abit
|
|||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v7.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.util.Base64.URL_SAFE
|
import android.util.Base64.URL_SAFE
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
|
@ -2,8 +2,8 @@ package ch.dissem.apps.abit
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.NavUtils
|
import androidx.core.app.NavUtils
|
||||||
import android.support.v7.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import com.mikepenz.materialize.MaterializeBuilder
|
import com.mikepenz.materialize.MaterializeBuilder
|
||||||
import kotlinx.android.synthetic.main.scrolling_toolbar_layout.*
|
import kotlinx.android.synthetic.main.scrolling_toolbar_layout.*
|
||||||
|
@ -18,7 +18,7 @@ package ch.dissem.apps.abit
|
|||||||
|
|
||||||
import android.graphics.*
|
import android.graphics.*
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.support.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import android.text.TextPaint
|
import android.text.TextPaint
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||||
import org.jetbrains.anko.collections.forEachWithIndex
|
import org.jetbrains.anko.collections.forEachWithIndex
|
||||||
@ -68,8 +68,8 @@ class Identicon(input: BitmessageAddress) : Drawable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun draw(canvas: Canvas) {
|
override fun draw(canvas: Canvas) {
|
||||||
val width = canvas.width.toFloat()
|
val width = bounds.width().toFloat()
|
||||||
val height = canvas.height.toFloat()
|
val height = bounds.height().toFloat()
|
||||||
draw(canvas, 0f, 0f, width, height)
|
draw(canvas, 0f, 0f, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,11 +124,11 @@ class MultiIdenticon(input: List<BitmessageAddress>, @ColorInt private val backg
|
|||||||
color = backgroundColor
|
color = backgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
private val identicons = input.sortedBy { it.isChan }.map { Identicon(it) }.take(4)
|
private val identicons = input.asSequence().sortedBy { it.isChan }.map { Identicon(it) }.take(4).toList()
|
||||||
|
|
||||||
override fun draw(canvas: Canvas) {
|
override fun draw(canvas: Canvas) {
|
||||||
val width = canvas.width.toFloat()
|
val width = bounds.width().toFloat()
|
||||||
val height = canvas.height.toFloat()
|
val height = bounds.height().toFloat()
|
||||||
|
|
||||||
when (identicons.size) {
|
when (identicons.size) {
|
||||||
0 -> canvas.drawCircle(width / 2, height / 2, width / 2, paint)
|
0 -> canvas.drawCircle(width / 2, height / 2, width / 2, paint)
|
||||||
|
@ -16,19 +16,18 @@
|
|||||||
|
|
||||||
package ch.dissem.apps.abit
|
package ch.dissem.apps.abit
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.content.ContextCompat
|
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import ch.dissem.apps.abit.adapter.AddressSelectorAdapter
|
import ch.dissem.apps.abit.adapter.AddressSelectorAdapter
|
||||||
import ch.dissem.apps.abit.service.Singleton
|
import ch.dissem.apps.abit.service.Singleton
|
||||||
import ch.dissem.bitmessage.wif.WifImporter
|
import ch.dissem.bitmessage.wif.WifImporter
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.decoration.SimpleListDividerDecorator
|
|
||||||
import org.ini4j.InvalidFileFormatException
|
import org.ini4j.InvalidFileFormatException
|
||||||
import org.jetbrains.anko.longToast
|
import org.jetbrains.anko.longToast
|
||||||
|
|
||||||
@ -47,34 +46,31 @@ class ImportIdentitiesFragment : Fragment() {
|
|||||||
inflater.inflate(R.layout.fragment_import_select_identities, container, false)
|
inflater.inflate(R.layout.fragment_import_select_identities, container, false)
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
val ctx = activity ?: throw IllegalStateException("No activity available")
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
val wifData = arguments.getString(WIF_DATA)
|
val wifData = arguments?.getString(WIF_DATA) ?: throw IllegalStateException("No WIF data")
|
||||||
val bmc = Singleton.getBitmessageContext(activity)
|
val bmc = Singleton.getBitmessageContext(ctx)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
importer = WifImporter(bmc, wifData)
|
importer = WifImporter(bmc, wifData)
|
||||||
} catch (e: InvalidFileFormatException) {
|
} catch (e: InvalidFileFormatException) {
|
||||||
longToast(R.string.invalid_wif_file)
|
ctx.longToast(R.string.invalid_wif_file)
|
||||||
activity.finish()
|
ctx.finish()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter = AddressSelectorAdapter(importer.getIdentities())
|
adapter = AddressSelectorAdapter(importer.getIdentities())
|
||||||
val layoutManager = LinearLayoutManager(
|
val layoutManager = LinearLayoutManager(
|
||||||
activity,
|
activity,
|
||||||
LinearLayoutManager.VERTICAL,
|
RecyclerView.VERTICAL,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
val recyclerView = view.findViewById<RecyclerView>(R.id.recycler_view)
|
val recyclerView = view.findViewById<RecyclerView>(R.id.recycler_view)
|
||||||
recyclerView.layoutManager = layoutManager
|
recyclerView.layoutManager = layoutManager
|
||||||
recyclerView.adapter = adapter
|
recyclerView.adapter = adapter
|
||||||
|
|
||||||
recyclerView.addItemDecoration(
|
recyclerView.addItemDecoration(DividerItemDecoration(ctx, DividerItemDecoration.HORIZONTAL))
|
||||||
SimpleListDividerDecorator(
|
|
||||||
ContextCompat.getDrawable(activity, R.drawable.list_divider_h), true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
view.findViewById<Button>(R.id.finish).setOnClickListener {
|
view.findViewById<Button>(R.id.finish).setOnClickListener {
|
||||||
importer.importAll(adapter.selected)
|
importer.importAll(adapter.selected)
|
||||||
@ -83,7 +79,7 @@ class ImportIdentitiesFragment : Fragment() {
|
|||||||
addIdentityEntry(selected)
|
addIdentityEntry(selected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
activity.finish()
|
ctx.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package ch.dissem.apps.abit
|
package ch.dissem.apps.abit
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.transaction
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christian Basler
|
* @author Christian Basler
|
||||||
@ -29,19 +30,20 @@ class ImportIdentityActivity : DetailActivity() {
|
|||||||
val wifData: String? = savedInstanceState?.getString(ImportIdentitiesFragment.WIF_DATA)
|
val wifData: String? = savedInstanceState?.getString(ImportIdentitiesFragment.WIF_DATA)
|
||||||
|
|
||||||
if (wifData == null) {
|
if (wifData == null) {
|
||||||
fragmentManager.beginTransaction()
|
supportFragmentManager.transaction {
|
||||||
.replace(R.id.content, InputWifFragment())
|
replace(R.id.content, InputWifFragment())
|
||||||
.commit()
|
}
|
||||||
} else {
|
} else {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putString(ImportIdentitiesFragment.WIF_DATA, wifData)
|
bundle.putString(ImportIdentitiesFragment.WIF_DATA, wifData)
|
||||||
|
|
||||||
val fragment = ImportIdentitiesFragment()
|
val fragment = ImportIdentitiesFragment().apply {
|
||||||
fragment.arguments = bundle
|
arguments = bundle
|
||||||
|
}
|
||||||
|
|
||||||
fragmentManager.beginTransaction()
|
supportFragmentManager.transaction {
|
||||||
.replace(R.id.content, fragment)
|
replace(R.id.content, fragment)
|
||||||
.commit()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,10 +16,11 @@
|
|||||||
|
|
||||||
package ch.dissem.apps.abit
|
package ch.dissem.apps.abit
|
||||||
|
|
||||||
import android.app.Fragment
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.transaction
|
||||||
import com.github.angads25.filepicker.model.DialogConfigs
|
import com.github.angads25.filepicker.model.DialogConfigs
|
||||||
import com.github.angads25.filepicker.model.DialogProperties
|
import com.github.angads25.filepicker.model.DialogProperties
|
||||||
import com.github.angads25.filepicker.view.FilePickerDialog
|
import com.github.angads25.filepicker.view.FilePickerDialog
|
||||||
@ -42,7 +43,7 @@ class InputWifFragment : Fragment() {
|
|||||||
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_import_input, container, false)
|
inflater.inflate(R.layout.fragment_import_input, container, false)
|
||||||
|
|
||||||
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
next.setOnClickListener {
|
next.setOnClickListener {
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
@ -52,9 +53,9 @@ class InputWifFragment : Fragment() {
|
|||||||
arguments = bundle
|
arguments = bundle
|
||||||
}
|
}
|
||||||
|
|
||||||
fragmentManager.beginTransaction()
|
fragmentManager?.transaction {
|
||||||
.replace(R.id.content, fragment)
|
replace(R.id.content, fragment)
|
||||||
.commit()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,11 +20,12 @@ import android.content.Intent
|
|||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.annotation.DrawableRes
|
|
||||||
import android.support.v4.app.Fragment
|
|
||||||
import android.support.v7.app.AppCompatActivity
|
|
||||||
import android.support.v7.widget.Toolbar
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.appcompat.widget.Toolbar
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.transaction
|
||||||
import ch.dissem.apps.abit.drawer.ProfileImageListener
|
import ch.dissem.apps.abit.drawer.ProfileImageListener
|
||||||
import ch.dissem.apps.abit.drawer.ProfileSelectionListener
|
import ch.dissem.apps.abit.drawer.ProfileSelectionListener
|
||||||
import ch.dissem.apps.abit.listener.ListSelectionListener
|
import ch.dissem.apps.abit.listener.ListSelectionListener
|
||||||
@ -32,7 +33,10 @@ import ch.dissem.apps.abit.repository.AndroidLabelRepository.Companion.LABEL_ARC
|
|||||||
import ch.dissem.apps.abit.repository.AndroidMessageRepository
|
import ch.dissem.apps.abit.repository.AndroidMessageRepository
|
||||||
import ch.dissem.apps.abit.service.Singleton
|
import ch.dissem.apps.abit.service.Singleton
|
||||||
import ch.dissem.apps.abit.service.Singleton.currentLabel
|
import ch.dissem.apps.abit.service.Singleton.currentLabel
|
||||||
import ch.dissem.apps.abit.util.*
|
import ch.dissem.apps.abit.util.getColor
|
||||||
|
import ch.dissem.apps.abit.util.getIcon
|
||||||
|
import ch.dissem.apps.abit.util.network
|
||||||
|
import ch.dissem.apps.abit.util.preferences
|
||||||
import ch.dissem.bitmessage.BitmessageContext
|
import ch.dissem.bitmessage.BitmessageContext
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||||
import ch.dissem.bitmessage.entity.Conversation
|
import ch.dissem.bitmessage.entity.Conversation
|
||||||
@ -51,6 +55,7 @@ import com.mikepenz.materialdrawer.model.interfaces.IProfile
|
|||||||
import com.mikepenz.materialdrawer.model.interfaces.Nameable
|
import com.mikepenz.materialdrawer.model.interfaces.Nameable
|
||||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDial
|
import io.github.kobakei.materialfabspeeddial.FabSpeedDial
|
||||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
import org.jetbrains.anko.doAsync
|
import org.jetbrains.anko.doAsync
|
||||||
import org.jetbrains.anko.uiThread
|
import org.jetbrains.anko.uiThread
|
||||||
@ -92,6 +97,8 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
|
|||||||
var hasDetailPane: Boolean = false
|
var hasDetailPane: Boolean = false
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
private var subscription: Disposable? = null
|
||||||
|
|
||||||
private lateinit var bmc: BitmessageContext
|
private lateinit var bmc: BitmessageContext
|
||||||
private lateinit var messageRepo: AndroidMessageRepository
|
private lateinit var messageRepo: AndroidMessageRepository
|
||||||
private lateinit var accountHeader: AccountHeader
|
private lateinit var accountHeader: AccountHeader
|
||||||
@ -294,11 +301,11 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
|
|||||||
|
|
||||||
uiThread {
|
uiThread {
|
||||||
if (intent.hasExtra(EXTRA_SHOW_LABEL)) {
|
if (intent.hasExtra(EXTRA_SHOW_LABEL)) {
|
||||||
currentLabel.value = intent.getSerializableExtra(EXTRA_SHOW_LABEL) as Label
|
currentLabel.onNext(intent.getSerializableExtra(EXTRA_SHOW_LABEL) as Label)
|
||||||
} else if (currentLabel.value == null) {
|
} else if (currentLabel.value == null) {
|
||||||
currentLabel.value = labels[0]
|
currentLabel.onNext(labels[0])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (label in labels) {
|
for (label in labels) {
|
||||||
addLabelEntry(label)
|
addLabelEntry(label)
|
||||||
}
|
}
|
||||||
@ -322,7 +329,7 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
|
|||||||
val itemList = supportFragmentManager.findFragmentById(R.id.item_list)
|
val itemList = supportFragmentManager.findFragmentById(R.id.item_list)
|
||||||
val tag = item.tag
|
val tag = item.tag
|
||||||
if (tag is Label) {
|
if (tag is Label) {
|
||||||
currentLabel.value = tag
|
currentLabel.onNext(tag)
|
||||||
if (tag.type == Label.Type.INBOX || tag == LABEL_ARCHIVE) {
|
if (tag.type == Label.Type.INBOX || tag == LABEL_ARCHIVE) {
|
||||||
if (itemList !is ConversationListFragment) {
|
if (itemList !is ConversationListFragment) {
|
||||||
changeList(ConversationListFragment())
|
changeList(ConversationListFragment())
|
||||||
@ -344,11 +351,10 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
R.string.settings -> {
|
R.string.settings -> {
|
||||||
supportFragmentManager
|
supportFragmentManager?.transaction {
|
||||||
.beginTransaction()
|
replace(R.id.item_list, SettingsFragment())
|
||||||
.replace(R.id.item_list, SettingsFragment())
|
addToBackStack(null)
|
||||||
.addToBackStack(null)
|
}
|
||||||
.commit()
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
R.string.full_node -> return true
|
R.string.full_node -> return true
|
||||||
@ -363,9 +369,9 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
|
|||||||
network.enableNode(false)
|
network.enableNode(false)
|
||||||
updateUnread()
|
updateUnread()
|
||||||
Singleton.getMessageListener(this).resetNotification()
|
Singleton.getMessageListener(this).resetNotification()
|
||||||
currentLabel.addObserver(this) { label ->
|
subscription = currentLabel.subscribe { label ->
|
||||||
if (label != null && label.id is Long) {
|
if (label.id is Long) {
|
||||||
drawer.setSelection(label.id as Long)
|
drawer.setSelection(label.id as Long, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
active = true
|
active = true
|
||||||
@ -373,7 +379,7 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
currentLabel.removeObserver(this)
|
subscription?.dispose()
|
||||||
super.onPause()
|
super.onPause()
|
||||||
active = false
|
active = false
|
||||||
}
|
}
|
||||||
@ -537,9 +543,8 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
|
|||||||
|
|
||||||
fun initFab(@DrawableRes drawableRes: Int, menu: FabSpeedDialMenu): FabSpeedDial {
|
fun initFab(@DrawableRes drawableRes: Int, menu: FabSpeedDialMenu): FabSpeedDial {
|
||||||
val fab = floatingActionButton ?: throw IllegalStateException("Fab must not be null")
|
val fab = floatingActionButton ?: throw IllegalStateException("Fab must not be null")
|
||||||
|
fab.hide()
|
||||||
fab.removeAllOnMenuItemClickListeners()
|
fab.removeAllOnMenuItemClickListeners()
|
||||||
fab.show()
|
|
||||||
fab.closeMenu()
|
|
||||||
val mainFab = fab.mainFab
|
val mainFab = fab.mainFab
|
||||||
mainFab.setImageResource(drawableRes)
|
mainFab.setImageResource(drawableRes)
|
||||||
fab.setMenu(menu)
|
fab.setMenu(menu)
|
||||||
@ -551,6 +556,8 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
|
|||||||
mainFab.setImageResource(drawableRes)
|
mainFab.setImageResource(drawableRes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fab.show()
|
||||||
|
fab.closeMenu()
|
||||||
return fab
|
return fab
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package ch.dissem.apps.abit
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.NavUtils
|
import androidx.core.app.NavUtils
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import ch.dissem.bitmessage.entity.Plaintext
|
import ch.dissem.bitmessage.entity.Plaintext
|
||||||
|
|
||||||
|
@ -19,11 +19,11 @@ package ch.dissem.apps.abit
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.annotation.IdRes
|
import androidx.annotation.IdRes
|
||||||
import android.support.v4.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.support.v7.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import android.support.v7.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import android.text.util.Linkify
|
import android.text.util.Linkify
|
||||||
import android.text.util.Linkify.WEB_URLS
|
import android.text.util.Linkify.WEB_URLS
|
||||||
import android.view.*
|
import android.view.*
|
||||||
|
@ -19,33 +19,28 @@ package ch.dissem.apps.abit
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.support.v4.content.ContextCompat
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import android.support.v7.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import android.support.v7.widget.RecyclerView.OnScrollListener
|
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_BROADCAST
|
import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_BROADCAST
|
||||||
import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_IDENTITY
|
import ch.dissem.apps.abit.ComposeMessageActivity.Companion.EXTRA_IDENTITY
|
||||||
|
import ch.dissem.apps.abit.adapter.EventListener
|
||||||
|
import ch.dissem.apps.abit.adapter.SwipeToDeleteCallback
|
||||||
import ch.dissem.apps.abit.adapter.SwipeableMessageAdapter
|
import ch.dissem.apps.abit.adapter.SwipeableMessageAdapter
|
||||||
import ch.dissem.apps.abit.listener.ListSelectionListener
|
import ch.dissem.apps.abit.listener.ListSelectionListener
|
||||||
import ch.dissem.apps.abit.repository.AndroidMessageRepository
|
import ch.dissem.apps.abit.repository.AndroidMessageRepository
|
||||||
import ch.dissem.apps.abit.service.Singleton
|
import ch.dissem.apps.abit.service.Singleton
|
||||||
import ch.dissem.apps.abit.service.Singleton.currentLabel
|
import ch.dissem.apps.abit.service.Singleton.currentLabel
|
||||||
import ch.dissem.apps.abit.util.preferences
|
import ch.dissem.apps.abit.util.preferences
|
||||||
import ch.dissem.bitmessage.entity.Plaintext
|
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.animator.SwipeDismissItemAnimator
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.decoration.SimpleListDividerDecorator
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
|
|
||||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
import kotlinx.android.synthetic.main.fragment_message_list.*
|
import kotlinx.android.synthetic.main.fragment_message_list.*
|
||||||
import org.jetbrains.anko.*
|
import org.jetbrains.anko.*
|
||||||
import org.jetbrains.anko.support.v4.alert
|
|
||||||
import org.jetbrains.anko.support.v4.onUiThread
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
private const val PAGE_SIZE = 15
|
private const val PAGE_SIZE = 15
|
||||||
@ -65,21 +60,20 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
private var isLoading = false
|
private var isLoading = false
|
||||||
private var isLastPage = false
|
private var isLastPage = false
|
||||||
|
|
||||||
|
private var subscription: Disposable? = null
|
||||||
|
|
||||||
private var layoutManager: LinearLayoutManager? = null
|
private var layoutManager: LinearLayoutManager? = null
|
||||||
private var swipeableMessageAdapter: SwipeableMessageAdapter? = null
|
private var swipeableMessageAdapter: SwipeableMessageAdapter? = null
|
||||||
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
|
|
||||||
private var recyclerViewSwipeManager: RecyclerViewSwipeManager? = null
|
|
||||||
private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null
|
|
||||||
|
|
||||||
private val recyclerViewOnScrollListener = object : OnScrollListener() {
|
private val recyclerViewOnScrollListener = object : OnScrollListener() {
|
||||||
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
layoutManager?.let { layoutManager ->
|
layoutManager?.let { layoutManager ->
|
||||||
val visibleItemCount = layoutManager.childCount
|
val visibleItemCount = layoutManager.childCount
|
||||||
val totalItemCount = layoutManager.itemCount
|
val totalItemCount = layoutManager.itemCount
|
||||||
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
|
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
|
||||||
|
|
||||||
if (!isLoading && !isLastPage) {
|
if (!isLoading && !isLastPage) {
|
||||||
if (visibleItemCount + firstVisibleItemPosition >= totalItemCount - 5
|
if (visibleItemCount + firstVisibleItemPosition >= totalItemCount - PAGE_SIZE
|
||||||
&& firstVisibleItemPosition >= 0
|
&& firstVisibleItemPosition >= 0
|
||||||
) {
|
) {
|
||||||
loadMoreItems()
|
loadMoreItems()
|
||||||
@ -94,6 +88,11 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
private lateinit var messageRepo: AndroidMessageRepository
|
private lateinit var messageRepo: AndroidMessageRepository
|
||||||
private var activateOnItemClick: Boolean = false
|
private var activateOnItemClick: Boolean = false
|
||||||
|
|
||||||
|
override fun setActivateOnItemClick(activateOnItemClick: Boolean) {
|
||||||
|
swipeableMessageAdapter?.activateOnItemClick = activateOnItemClick
|
||||||
|
this.activateOnItemClick = activateOnItemClick
|
||||||
|
}
|
||||||
|
|
||||||
private val backStack = Stack<Label>()
|
private val backStack = Stack<Label>()
|
||||||
|
|
||||||
fun loadMoreItems() {
|
fun loadMoreItems() {
|
||||||
@ -107,7 +106,7 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
PAGE_SIZE,
|
PAGE_SIZE,
|
||||||
context?.preferences?.separateIdentities == true && label?.type != Label.Type.BROADCAST
|
context?.preferences?.separateIdentities == true && label?.type != Label.Type.BROADCAST
|
||||||
)
|
)
|
||||||
onUiThread {
|
uiThread {
|
||||||
messageAdapter.addAll(messages)
|
messageAdapter.addAll(messages)
|
||||||
isLoading = false
|
isLoading = false
|
||||||
isLastPage = messages.size < PAGE_SIZE
|
isLastPage = messages.size < PAGE_SIZE
|
||||||
@ -128,12 +127,12 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
initFab(activity)
|
initFab(activity)
|
||||||
messageRepo = Singleton.getMessageRepository(activity)
|
messageRepo = Singleton.getMessageRepository(activity)
|
||||||
|
|
||||||
currentLabel.addObserver(this) { new -> doUpdateList(new) }
|
subscription = currentLabel.subscribe { new -> doUpdateList(new) }
|
||||||
doUpdateList(currentLabel.value)
|
doUpdateList(currentLabel.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
currentLabel.removeObserver(this)
|
subscription?.dispose()
|
||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +150,7 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
menuItem.isVisible = label.type == Label.Type.TRASH
|
menuItem.isVisible = label.type == Label.Type.TRASH
|
||||||
mainActivity?.apply {
|
MainActivity.apply {
|
||||||
if ("archive" == label.toString()) {
|
if ("archive" == label.toString()) {
|
||||||
updateTitle(getString(R.string.archive))
|
updateTitle(getString(R.string.archive))
|
||||||
} else {
|
} else {
|
||||||
@ -176,81 +175,37 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
|
|
||||||
val context = context ?: throw IllegalStateException("No context available")
|
val context = context ?: throw IllegalStateException("No context available")
|
||||||
|
|
||||||
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
|
||||||
|
|
||||||
// touch guard manager (this class is required to suppress scrolling while swipe-dismiss
|
|
||||||
// animation is running)
|
|
||||||
val touchActionGuardManager = RecyclerViewTouchActionGuardManager().apply {
|
|
||||||
setInterceptVerticalScrollingWhileAnimationRunning(true)
|
|
||||||
isEnabled = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// swipe manager
|
|
||||||
val swipeManager = RecyclerViewSwipeManager()
|
|
||||||
|
|
||||||
//swipeableMessageAdapter
|
|
||||||
val adapter = SwipeableMessageAdapter().apply {
|
|
||||||
setActivateOnItemClick(activateOnItemClick)
|
|
||||||
}
|
|
||||||
adapter.eventListener = object : SwipeableMessageAdapter.EventListener {
|
|
||||||
override fun onItemDeleted(item: Plaintext) {
|
|
||||||
if (MessageDetailFragment.isInTrash(item)) {
|
|
||||||
Singleton.labeler.delete(item)
|
|
||||||
messageRepo.remove(item)
|
|
||||||
} else {
|
|
||||||
Singleton.labeler.delete(item)
|
|
||||||
messageRepo.save(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemArchived(item: Plaintext) {
|
|
||||||
Singleton.labeler.archive(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemViewClicked(v: View?) {
|
|
||||||
val position = recycler_view.getChildAdapterPosition(v)
|
|
||||||
adapter.setSelectedPosition(position)
|
|
||||||
if (position != RecyclerView.NO_POSITION) {
|
|
||||||
val item = adapter.getItem(position)
|
|
||||||
MainActivity.apply { onItemSelected(item) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wrap for swiping
|
|
||||||
wrappedAdapter = swipeManager.createWrappedAdapter(adapter)
|
|
||||||
|
|
||||||
val animator = SwipeDismissItemAnimator()
|
|
||||||
|
|
||||||
// Change animations are enabled by default since support-v7-recyclerview v22.
|
|
||||||
// Disable the change animation in order to make turning back animation of swiped item
|
|
||||||
// works properly.
|
|
||||||
animator.supportsChangeAnimations = false
|
|
||||||
|
|
||||||
recycler_view.layoutManager = layoutManager
|
recycler_view.layoutManager = layoutManager
|
||||||
recycler_view.adapter = wrappedAdapter // requires *wrapped* swipeableMessageAdapter
|
swipeableMessageAdapter = SwipeableMessageAdapter(context).apply {
|
||||||
recycler_view.itemAnimator = animator
|
activateOnItemClick = this@MessageListFragment.activateOnItemClick
|
||||||
|
}
|
||||||
|
recycler_view.adapter = swipeableMessageAdapter // requires *wrapped* swipeableMessageAdapter
|
||||||
recycler_view.addOnScrollListener(recyclerViewOnScrollListener)
|
recycler_view.addOnScrollListener(recyclerViewOnScrollListener)
|
||||||
|
|
||||||
recycler_view.addItemDecoration(
|
val dirs = when (currentLabel.value?.type) {
|
||||||
SimpleListDividerDecorator(
|
Label.Type.TRASH -> ItemTouchHelper.LEFT
|
||||||
ContextCompat.getDrawable(context, R.drawable.list_divider_h), true
|
else -> ItemTouchHelper.LEFT + ItemTouchHelper.RIGHT
|
||||||
)
|
}
|
||||||
)
|
|
||||||
|
|
||||||
// NOTE:
|
val swipeHandler = SwipeToDeleteCallback(context, dirs, object : EventListener {
|
||||||
// The initialization order is very important! This order determines the priority of
|
override fun onItemDeleted(position: Int) {
|
||||||
// touch event handling.
|
context.toast("Deleted")
|
||||||
//
|
}
|
||||||
// priority: TouchActionGuard > Swipe > DragAndDrop
|
|
||||||
touchActionGuardManager.attachRecyclerView(recycler_view)
|
|
||||||
swipeManager.attachRecyclerView(recycler_view)
|
|
||||||
|
|
||||||
recyclerViewTouchActionGuardManager = touchActionGuardManager
|
override fun onItemArchived(position: Int) {
|
||||||
recyclerViewSwipeManager = swipeManager
|
context.toast("Archived")
|
||||||
swipeableMessageAdapter = adapter
|
}
|
||||||
|
|
||||||
Singleton.updateMessageListAdapterInListener(adapter)
|
override fun onItemSelected(position: Int) {
|
||||||
|
context.toast("Selected")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
val itemTouchHelper = ItemTouchHelper(swipeHandler)
|
||||||
|
itemTouchHelper.attachToRecyclerView(recycler_view)
|
||||||
|
|
||||||
|
// FIXME Singleton.updateMessageListAdapterInListener(adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initFab(context: MainActivity) {
|
private fun initFab(context: MainActivity) {
|
||||||
@ -286,18 +241,6 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
recyclerViewSwipeManager?.release()
|
|
||||||
recyclerViewSwipeManager = null
|
|
||||||
|
|
||||||
recyclerViewTouchActionGuardManager?.release()
|
|
||||||
recyclerViewTouchActionGuardManager = null
|
|
||||||
|
|
||||||
recycler_view.itemAnimator = null
|
|
||||||
recycler_view.adapter = null
|
|
||||||
|
|
||||||
wrappedAdapter?.let { WrapperAdapterUtils.releaseAll(it) }
|
|
||||||
wrappedAdapter = null
|
|
||||||
|
|
||||||
swipeableMessageAdapter = null
|
swipeableMessageAdapter = null
|
||||||
layoutManager = null
|
layoutManager = null
|
||||||
|
|
||||||
@ -308,7 +251,7 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
inflater.inflate(R.menu.message_list, menu)
|
inflater.inflate(R.menu.message_list, menu)
|
||||||
emptyTrashMenuItem = menu.findItem(R.id.empty_trash)
|
emptyTrashMenuItem = menu.findItem(R.id.empty_trash)
|
||||||
deleteAllMenuItem = menu.findItem(R.id.delete_all)
|
deleteAllMenuItem = menu.findItem(R.id.delete_all)
|
||||||
currentLabel.value?.let { doUpdateList(it) }
|
// currentLabel.value?.let { doUpdateList(it) }
|
||||||
super.onCreateOptionsMenu(menu, inflater)
|
super.onCreateOptionsMenu(menu, inflater)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,9 +267,10 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
}
|
}
|
||||||
R.id.delete_all -> {
|
R.id.delete_all -> {
|
||||||
currentLabel.value?.let { label ->
|
currentLabel.value?.let { label ->
|
||||||
|
context?.apply {
|
||||||
alert(
|
alert(
|
||||||
title = R.string.delete_all_messages_in_list,
|
R.string.delete_all_messages_in_list,
|
||||||
message = R.string.delete_all_messages_in_list_ask
|
R.string.delete_all_messages_in_list_ask
|
||||||
) {
|
) {
|
||||||
positiveButton(R.string.delete) {
|
positiveButton(R.string.delete) {
|
||||||
deleteAllMessages(label)
|
deleteAllMessages(label)
|
||||||
@ -334,6 +278,7 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
cancelButton { }
|
cancelButton { }
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
else -> return false
|
else -> return false
|
||||||
@ -351,18 +296,13 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun updateList(label: Label) {
|
override fun updateList(label: Label) {
|
||||||
currentLabel.value = label
|
currentLabel.onNext(label)
|
||||||
}
|
|
||||||
|
|
||||||
override fun setActivateOnItemClick(activateOnItemClick: Boolean) {
|
|
||||||
swipeableMessageAdapter?.setActivateOnItemClick(activateOnItemClick)
|
|
||||||
this.activateOnItemClick = activateOnItemClick
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showPreviousList() = if (backStack.isEmpty()) {
|
override fun showPreviousList() = if (backStack.isEmpty()) {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
currentLabel.value = backStack.pop()
|
currentLabel.onNext(backStack.pop())
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,16 +23,11 @@ import android.content.Intent
|
|||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.support.v4.app.Fragment
|
|
||||||
import android.support.v4.content.ContextCompat
|
|
||||||
import android.support.v4.content.FileProvider.getUriForFile
|
|
||||||
import android.support.v7.preference.Preference
|
|
||||||
import android.support.v7.preference.Preference.OnPreferenceChangeListener
|
|
||||||
import android.support.v7.preference.PreferenceFragmentCompat
|
|
||||||
import android.support.v7.preference.PreferenceScreen
|
|
||||||
import android.support.v7.preference.SwitchPreferenceCompat
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.core.content.FileProvider.getUriForFile
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import androidx.preference.SwitchPreferenceCompat
|
||||||
import ch.dissem.apps.abit.service.BatchProcessorService
|
import ch.dissem.apps.abit.service.BatchProcessorService
|
||||||
import ch.dissem.apps.abit.service.SimpleJob
|
import ch.dissem.apps.abit.service.SimpleJob
|
||||||
import ch.dissem.apps.abit.service.Singleton
|
import ch.dissem.apps.abit.service.Singleton
|
||||||
@ -43,15 +38,15 @@ import ch.dissem.bitmessage.entity.Plaintext
|
|||||||
import com.mikepenz.aboutlibraries.Libs
|
import com.mikepenz.aboutlibraries.Libs
|
||||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
import com.mikepenz.aboutlibraries.LibsBuilder
|
||||||
import org.jetbrains.anko.doAsync
|
import org.jetbrains.anko.doAsync
|
||||||
import org.jetbrains.anko.support.v4.indeterminateProgressDialog
|
import org.jetbrains.anko.indeterminateProgressDialog
|
||||||
import org.jetbrains.anko.support.v4.startActivity
|
import org.jetbrains.anko.startActivity
|
||||||
import org.jetbrains.anko.uiThread
|
import org.jetbrains.anko.uiThread
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christian Basler
|
* @author Christian Basler
|
||||||
*/
|
*/
|
||||||
class SettingsFragment : PreferenceFragmentCompat(), PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
|
class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
|
|
||||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
setPreferencesFromResource(R.xml.preferences, rootKey)
|
setPreferencesFromResource(R.xml.preferences, rootKey)
|
||||||
@ -117,9 +112,9 @@ class SettingsFragment : PreferenceFragmentCompat(), PreferenceFragmentCompat.On
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun exportClickListener() = Preference.OnPreferenceClickListener {
|
private fun exportClickListener() = Preference.OnPreferenceClickListener {
|
||||||
val ctx = context ?: throw IllegalStateException("No context available")
|
val ctx = activity ?: throw IllegalStateException("No context available")
|
||||||
|
|
||||||
indeterminateProgressDialog(R.string.export_data_summary, R.string.export_data).apply {
|
ctx.indeterminateProgressDialog(R.string.export_data_summary, R.string.export_data).apply {
|
||||||
doAsync {
|
doAsync {
|
||||||
val exportDirectory = ctx.preferences.exportDirectory
|
val exportDirectory = ctx.preferences.exportDirectory
|
||||||
exportDirectory.mkdirs()
|
exportDirectory.mkdirs()
|
||||||
@ -152,20 +147,20 @@ class SettingsFragment : PreferenceFragmentCompat(), PreferenceFragmentCompat.On
|
|||||||
if (activity.hasDetailPane) {
|
if (activity.hasDetailPane) {
|
||||||
activity.setDetailView(StatusFragment())
|
activity.setDetailView(StatusFragment())
|
||||||
} else {
|
} else {
|
||||||
startActivity<StatusActivity>()
|
activity.startActivity<StatusActivity>()
|
||||||
}
|
}
|
||||||
return@OnPreferenceClickListener true
|
return@OnPreferenceClickListener true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
val ctx = context ?: throw IllegalStateException("No context available")
|
val ctx = activity ?: throw IllegalStateException("No context available")
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
WRITE_EXPORT_REQUEST_CODE -> ctx.preferences.cleanupExportDirectory()
|
WRITE_EXPORT_REQUEST_CODE -> ctx.preferences.cleanupExportDirectory()
|
||||||
READ_IMPORT_REQUEST_CODE -> {
|
READ_IMPORT_REQUEST_CODE -> {
|
||||||
if (resultCode == Activity.RESULT_OK && data?.data != null) {
|
if (resultCode == Activity.RESULT_OK && data?.data != null) {
|
||||||
indeterminateProgressDialog(R.string.import_data_summary, R.string.import_data).apply {
|
ctx.indeterminateProgressDialog(R.string.import_data_summary, R.string.import_data).apply {
|
||||||
doAsync {
|
doAsync {
|
||||||
Exports.importData(data.data, ctx)
|
Exports.importData(data.data!!, ctx)
|
||||||
uiThread {
|
uiThread {
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
@ -224,40 +219,41 @@ class SettingsFragment : PreferenceFragmentCompat(), PreferenceFragmentCompat.On
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun emulateConversationChangeListener(conversationInit: Preference?) =
|
private fun emulateConversationChangeListener(conversationInit: Preference?) =
|
||||||
OnPreferenceChangeListener { _, newValue ->
|
Preference.OnPreferenceChangeListener { _, newValue ->
|
||||||
conversationInit?.isEnabled = newValue as Boolean
|
conversationInit?.isEnabled = newValue as Boolean
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun connectivityChangeListener() =
|
private fun connectivityChangeListener() =
|
||||||
OnPreferenceChangeListener { _, _ ->
|
Preference.OnPreferenceChangeListener { _, _ ->
|
||||||
context?.network?.scheduleNodeStart()
|
activity?.network?.scheduleNodeStart()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
// The why-is-it-so-damn-hard-to-group-preferences section
|
// The why-is-it-so-damn-hard-to-group-preferences section
|
||||||
override fun getCallbackFragment(): Fragment = this
|
// FIXME: maybe this is once again necessary, maybe not. Test!
|
||||||
|
// override fun getCallbackFragment(): Fragment = this
|
||||||
override fun onPreferenceStartScreen(
|
//
|
||||||
preferenceFragmentCompat: PreferenceFragmentCompat,
|
// override fun onPreferenceStartScreen(
|
||||||
preferenceScreen: PreferenceScreen
|
// preferenceFragmentCompat: PreferenceFragment,
|
||||||
): Boolean {
|
// preferenceScreen: PreferenceScreen
|
||||||
fragmentManager?.beginTransaction()?.let { ft ->
|
// ): Boolean {
|
||||||
val fragment = SettingsFragment()
|
// fragmentManager?.beginTransaction()?.let { ft ->
|
||||||
fragment.arguments = Bundle().apply {
|
// val fragment = SettingsFragment()
|
||||||
putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.key)
|
// fragment.arguments = Bundle().apply {
|
||||||
}
|
// putString(PreferenceFragment.ARG_PREFERENCE_ROOT, preferenceScreen.key)
|
||||||
ft.add(R.id.item_list, fragment, preferenceScreen.key)
|
// }
|
||||||
ft.addToBackStack(preferenceScreen.key)
|
// ft.add(R.id.item_list, fragment, preferenceScreen.key)
|
||||||
ft.commit()
|
// ft.addToBackStack(preferenceScreen.key)
|
||||||
}
|
// ft.commit()
|
||||||
return true
|
// }
|
||||||
}
|
// return true
|
||||||
|
// }
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
//
|
||||||
super.onViewCreated(view, savedInstanceState)
|
// override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
context?.let { ctx -> view.setBackgroundColor(ContextCompat.getColor(ctx, R.color.contentBackground)) }
|
// super.onViewCreated(view, savedInstanceState)
|
||||||
}
|
// context?.let { ctx -> view.setBackgroundColor(ContextCompat.getColor(ctx, R.color.contentBackground)) }
|
||||||
|
// }
|
||||||
// End of the why-is-it-so-damn-hard-to-group-preferences section
|
// End of the why-is-it-so-damn-hard-to-group-preferences section
|
||||||
// Afterthought: here it looks so simple: https://developer.android.com/guide/topics/ui/settings.html
|
// Afterthought: here it looks so simple: https://developer.android.com/guide/topics/ui/settings.html
|
||||||
// Remind me, why do we need to use PreferenceFragmentCompat?
|
// Remind me, why do we need to use PreferenceFragmentCompat?
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
package ch.dissem.apps.abit
|
package ch.dissem.apps.abit
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v7.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import ch.dissem.apps.abit.service.Singleton
|
import ch.dissem.apps.abit.service.Singleton
|
||||||
import com.mikepenz.materialize.MaterializeBuilder
|
import com.mikepenz.materialize.MaterializeBuilder
|
||||||
import kotlinx.android.synthetic.main.activity_status.*
|
import kotlinx.android.synthetic.main.activity_status.*
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
package ch.dissem.apps.abit
|
package ch.dissem.apps.abit
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v4.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package ch.dissem.apps.abit.adapter
|
package ch.dissem.apps.abit.adapter
|
||||||
|
|
||||||
import android.support.v7.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -31,7 +31,7 @@ import java.util.*
|
|||||||
*/
|
*/
|
||||||
class AddressSelectorAdapter(identities: List<BitmessageAddress>) : RecyclerView.Adapter<AddressSelectorAdapter.ViewHolder>() {
|
class AddressSelectorAdapter(identities: List<BitmessageAddress>) : RecyclerView.Adapter<AddressSelectorAdapter.ViewHolder>() {
|
||||||
|
|
||||||
private val data = identities.map { Selectable(it) }.toMutableList()
|
private val data = identities.asSequence().map { Selectable(it) }.toMutableList()
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
val inflater = LayoutInflater.from(parent.context)
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
@ -63,7 +63,7 @@ class AddressSelectorAdapter(identities: List<BitmessageAddress>) : RecyclerView
|
|||||||
|
|
||||||
val selected: List<BitmessageAddress>
|
val selected: List<BitmessageAddress>
|
||||||
get() {
|
get() {
|
||||||
return data
|
return data.asSequence()
|
||||||
.filter { it.selected }
|
.filter { it.selected }
|
||||||
.mapTo(LinkedList()) { it.data }
|
.mapTo(LinkedList()) { it.data }
|
||||||
}
|
}
|
||||||
|
@ -142,5 +142,4 @@ class ContactAdapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun indexOf(element: BitmessageAddress) = originalData.indexOf(element)
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package ch.dissem.apps.abit.adapter
|
package ch.dissem.apps.abit.adapter
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.support.v4.app.Fragment
|
|
||||||
import android.support.v7.widget.GridLayoutManager
|
|
||||||
import android.support.v7.widget.PopupMenu
|
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.text.util.Linkify
|
import android.text.util.Linkify
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import ch.dissem.apps.abit.*
|
import ch.dissem.apps.abit.*
|
||||||
import ch.dissem.apps.abit.service.Singleton
|
import ch.dissem.apps.abit.service.Singleton
|
||||||
import ch.dissem.apps.abit.util.Constants
|
import ch.dissem.apps.abit.util.Constants
|
||||||
@ -19,18 +19,19 @@ import ch.dissem.bitmessage.entity.Conversation
|
|||||||
import ch.dissem.bitmessage.entity.Plaintext
|
import ch.dissem.bitmessage.entity.Plaintext
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||||
import ch.dissem.bitmessage.ports.MessageRepository
|
import ch.dissem.bitmessage.ports.MessageRepository
|
||||||
|
import io.reactivex.subjects.BehaviorSubject
|
||||||
|
|
||||||
|
|
||||||
class ConversationAdapter internal constructor(
|
class ConversationAdapter internal constructor(
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
private val parent: Fragment,
|
private val parent: Fragment,
|
||||||
conversation: Conversation,
|
conversation: Conversation,
|
||||||
private val label: Label?
|
label: BehaviorSubject<Label>
|
||||||
) : RecyclerView.Adapter<ConversationAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<ConversationAdapter.ViewHolder>() {
|
||||||
|
|
||||||
private val messageRepo = Singleton.getMessageRepository(ctx)
|
private val messageRepo = Singleton.getMessageRepository(ctx)
|
||||||
|
|
||||||
private var filteredMessages = conversation.messages.filter { label == null || it.labels.any { it == label } }
|
private var filteredMessages = label.value?.let { l -> conversation.messages.filter { m -> m.labels.any { it == l } } } ?: emptyList()
|
||||||
|
|
||||||
override fun onCreateViewHolder(
|
override fun onCreateViewHolder(
|
||||||
parent: ViewGroup,
|
parent: ViewGroup,
|
||||||
@ -98,13 +99,14 @@ class ConversationAdapter internal constructor(
|
|||||||
val sender = itemView.findViewById<TextView>(R.id.sender)!!
|
val sender = itemView.findViewById<TextView>(R.id.sender)!!
|
||||||
val recipient = itemView.findViewById<TextView>(R.id.recipient)!!
|
val recipient = itemView.findViewById<TextView>(R.id.recipient)!!
|
||||||
val status = itemView.findViewById<ImageView>(R.id.status)!!
|
val status = itemView.findViewById<ImageView>(R.id.status)!!
|
||||||
val menu = itemView.findViewById<ImageView>(R.id.menu)!!.also { view ->
|
val menu = itemView.findViewById<ImageView>(R.id.menu)!!.apply {
|
||||||
view.setOnClickListener {
|
setOnClickListener { view ->
|
||||||
val popup = PopupMenu(itemView.context, view)
|
PopupMenu(itemView.context, view).apply {
|
||||||
popup.menuInflater.inflate(R.menu.message, popup.menu)
|
|
||||||
popup.setOnMenuItemClickListener {
|
menuInflater.inflate(R.menu.message, menu)
|
||||||
|
setOnMenuItemClickListener { menuItem ->
|
||||||
item?.let { item ->
|
item?.let { item ->
|
||||||
when (it.itemId) {
|
when (menuItem.itemId) {
|
||||||
R.id.reply -> {
|
R.id.reply -> {
|
||||||
ComposeMessageActivity.launchReplyTo(parent, item)
|
ComposeMessageActivity.launchReplyTo(parent, item)
|
||||||
true
|
true
|
||||||
@ -142,7 +144,9 @@ class ConversationAdapter internal constructor(
|
|||||||
}
|
}
|
||||||
} ?: false
|
} ?: false
|
||||||
}
|
}
|
||||||
popup.show()
|
show()
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val text = itemView.findViewById<TextView>(R.id.text)!!.apply {
|
val text = itemView.findViewById<TextView>(R.id.text)!!.apply {
|
||||||
|
@ -2,8 +2,8 @@ package ch.dissem.apps.abit.adapter
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.support.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import android.support.v7.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -0,0 +1,312 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Haruki Hasegawa
|
||||||
|
* Copyright 2016 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.dissem.apps.abit.adapter
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.*
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import ch.dissem.apps.abit.Identicon
|
||||||
|
import ch.dissem.apps.abit.MultiIdenticon
|
||||||
|
import ch.dissem.apps.abit.R
|
||||||
|
import ch.dissem.apps.abit.util.Strings.prepareMessageExtract
|
||||||
|
import ch.dissem.apps.abit.util.getDrawable
|
||||||
|
import ch.dissem.apps.abit.util.getString
|
||||||
|
import ch.dissem.bitmessage.entity.Conversation
|
||||||
|
import ch.dissem.bitmessage.entity.Plaintext
|
||||||
|
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapted from the basic swipeable example by Haruki Hasegawa. See
|
||||||
|
*
|
||||||
|
* @author Christian Basler
|
||||||
|
* @see [https://github.com/h6ah4i/android-advancedrecyclerview](https://github.com/h6ah4i/android-advancedrecyclerview)
|
||||||
|
*/
|
||||||
|
abstract class SwipeableAdapter<T, H>(val ctx: Context) :
|
||||||
|
RecyclerView.Adapter<H>() where H : SwipeableAdapter.AbstractViewHolder {
|
||||||
|
|
||||||
|
protected val data = LinkedList<T>()
|
||||||
|
var eventListener: EventListener? = null
|
||||||
|
|
||||||
|
protected var label: Label? = null
|
||||||
|
var selectedPosition = -1
|
||||||
|
set(value) {
|
||||||
|
val oldPosition = field
|
||||||
|
field = value
|
||||||
|
notifyItemChanged(oldPosition)
|
||||||
|
notifyItemChanged(value)
|
||||||
|
}
|
||||||
|
var activateOnItemClick: Boolean = false
|
||||||
|
|
||||||
|
protected val labelUnknown: String = ctx.getString(R.string.unknown)
|
||||||
|
|
||||||
|
open class AbstractViewHolder(v: View, adapter: SwipeableAdapter<*, *>) : RecyclerView.ViewHolder(v) {
|
||||||
|
|
||||||
|
val container = v.findViewById<FrameLayout>(R.id.container)!!
|
||||||
|
|
||||||
|
init {
|
||||||
|
itemView.setOnClickListener { adapter.eventListener?.onItemSelected(adapterPosition) }
|
||||||
|
container.setOnClickListener { adapter.eventListener?.onItemSelected(adapterPosition) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
// SwipeableItemAdapter requires stable ID, and also
|
||||||
|
// have to implement the getItemId() method appropriately.
|
||||||
|
setHasStableIds(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: H, position: Int) {
|
||||||
|
val item = data[position]
|
||||||
|
|
||||||
|
holder.apply {
|
||||||
|
if (activateOnItemClick) {
|
||||||
|
container.setBackgroundResource(
|
||||||
|
if (position == selectedPosition)
|
||||||
|
R.drawable.bg_item_selected_state
|
||||||
|
else
|
||||||
|
R.drawable.bg_item_normal_state
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
setData(holder, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun setData(holder: H, item: T)
|
||||||
|
|
||||||
|
fun add(item: T) {
|
||||||
|
val index = data.size
|
||||||
|
data.add(item)
|
||||||
|
notifyItemInserted(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addFirst(item: T) {
|
||||||
|
data.addFirst(item)
|
||||||
|
notifyItemInserted(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addAll(items: Collection<T>) {
|
||||||
|
val index = data.size
|
||||||
|
data.addAll(items)
|
||||||
|
notifyItemRangeInserted(index, items.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove(item: T) {
|
||||||
|
val itemId = getItemId(item)
|
||||||
|
val index = data.indexOfFirst { getItemId(it) == itemId }
|
||||||
|
if (index >= 0) {
|
||||||
|
removeAt(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeAt(index: Int) {
|
||||||
|
data.removeAt(index)
|
||||||
|
notifyItemRemoved(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemId(position: Int): Long {
|
||||||
|
return getItemId(data[position])
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun getItemId(item: T): Long
|
||||||
|
|
||||||
|
abstract fun update(item: T)
|
||||||
|
|
||||||
|
fun clear(newLabel: Label?) {
|
||||||
|
label = newLabel
|
||||||
|
data.clear()
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getItem(position: Int) = data[position]
|
||||||
|
|
||||||
|
override fun getItemCount() = data.size
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class SwipeableConversationAdapter(ctx: Context) : SwipeableAdapter<Conversation, SwipeableConversationAdapter.ViewHolder>(ctx) {
|
||||||
|
override fun getItemId(item: Conversation) = item.id.leastSignificantBits
|
||||||
|
|
||||||
|
override fun update(item: Conversation) {
|
||||||
|
val index = data.indexOfFirst { it.id == item.id }
|
||||||
|
if (index >= 0) {
|
||||||
|
data[index] = item
|
||||||
|
notifyItemChanged(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
|
val v = inflater.inflate(R.layout.conversation_row, parent, false)
|
||||||
|
return ViewHolder(v, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setData(holder: ViewHolder, item: Conversation) {
|
||||||
|
holder.apply {
|
||||||
|
avatar.setImageDrawable(MultiIdenticon(item.participants))
|
||||||
|
|
||||||
|
sender.text = item.participants.sortedBy {
|
||||||
|
(it.alias?.let { 0 } ?: 1) + if (it.isChan) 2 else 0
|
||||||
|
}.map { it.alias ?: labelUnknown }.distinct().joinToString()
|
||||||
|
subject.text = prepareMessageExtract(item.subject)
|
||||||
|
extract.text = prepareMessageExtract(item.extract)
|
||||||
|
item.messages.count { it.labels.contains(label) }.let { size ->
|
||||||
|
if (size <= 1) {
|
||||||
|
count.text = ""
|
||||||
|
} else {
|
||||||
|
count.text = size.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (item.hasUnread()) {
|
||||||
|
sender.typeface = Typeface.DEFAULT_BOLD
|
||||||
|
subject.typeface = Typeface.DEFAULT_BOLD
|
||||||
|
} else {
|
||||||
|
sender.typeface = Typeface.DEFAULT
|
||||||
|
subject.typeface = Typeface.DEFAULT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder(v: View, adapter: SwipeableConversationAdapter) : AbstractViewHolder(v, adapter) {
|
||||||
|
val avatar = v.findViewById<ImageView>(R.id.avatar)!!
|
||||||
|
val status = v.findViewById<ImageView>(R.id.status)!!
|
||||||
|
val sender = v.findViewById<TextView>(R.id.sender)!!
|
||||||
|
val subject = v.findViewById<TextView>(R.id.subject)!!
|
||||||
|
val extract = v.findViewById<TextView>(R.id.text)!!
|
||||||
|
val count = v.findViewById<TextView>(R.id.count)!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SwipeableMessageAdapter(ctx: Context) : SwipeableAdapter<Plaintext, SwipeableMessageAdapter.ViewHolder>(ctx) {
|
||||||
|
override fun getItemId(item: Plaintext) = item.id as Long
|
||||||
|
|
||||||
|
override fun update(item: Plaintext) {
|
||||||
|
val index = data.indexOfFirst { it.id == item.id }
|
||||||
|
if (index >= 0) {
|
||||||
|
data[index] = item
|
||||||
|
notifyItemChanged(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
|
val v = inflater.inflate(R.layout.message_row, parent, false)
|
||||||
|
return ViewHolder(v, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setData(holder: ViewHolder, item: Plaintext) {
|
||||||
|
holder.apply {
|
||||||
|
avatar.setImageDrawable(Identicon(item.from))
|
||||||
|
status.setImageResource(item.status.getDrawable())
|
||||||
|
status.contentDescription = holder.status.context.getString(item.status.getString())
|
||||||
|
|
||||||
|
sender.text = item.from.toString()
|
||||||
|
subject.text = prepareMessageExtract(item.subject)
|
||||||
|
extract.text = prepareMessageExtract(item.text)
|
||||||
|
if (item.isUnread()) {
|
||||||
|
sender.typeface = Typeface.DEFAULT_BOLD
|
||||||
|
subject.typeface = Typeface.DEFAULT_BOLD
|
||||||
|
} else {
|
||||||
|
sender.typeface = Typeface.DEFAULT
|
||||||
|
subject.typeface = Typeface.DEFAULT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder(v: View, adapter: SwipeableMessageAdapter) : AbstractViewHolder(v, adapter) {
|
||||||
|
val avatar = v.findViewById<ImageView>(R.id.avatar)!!
|
||||||
|
val status = v.findViewById<ImageView>(R.id.status)!!
|
||||||
|
val sender = v.findViewById<TextView>(R.id.sender)!!
|
||||||
|
val subject = v.findViewById<TextView>(R.id.subject)!!
|
||||||
|
val extract = v.findViewById<TextView>(R.id.text)!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SwipeToDeleteCallback(ctx: Context, swipeDirs: Int, private val eventListener: EventListener) : ItemTouchHelper.SimpleCallback(0, swipeDirs) {
|
||||||
|
|
||||||
|
private val backgroundLeft = ContextCompat.getDrawable(ctx, R.drawable.bg_swipe_item_left)!!
|
||||||
|
private val backgroundRight = ContextCompat.getDrawable(ctx, R.drawable.bg_swipe_item_right)!!
|
||||||
|
private val clearPaint = Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) }
|
||||||
|
|
||||||
|
|
||||||
|
override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
|
||||||
|
/**
|
||||||
|
* To disable "swipe" for specific item return 0 here.
|
||||||
|
* For example:
|
||||||
|
* if (viewHolder?.itemViewType == YourAdapter.SOME_TYPE) return 0
|
||||||
|
* if (viewHolder?.adapterPosition == 0) return 0
|
||||||
|
*/
|
||||||
|
if (viewHolder.adapterPosition == 10) return 0
|
||||||
|
return super.getMovementFlags(recyclerView, viewHolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder) = false
|
||||||
|
|
||||||
|
override fun onChildDraw(
|
||||||
|
c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
|
||||||
|
dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean
|
||||||
|
) {
|
||||||
|
|
||||||
|
val itemView = viewHolder.itemView
|
||||||
|
val isCanceled = dX == 0f && !isCurrentlyActive
|
||||||
|
|
||||||
|
if (isCanceled) {
|
||||||
|
clearCanvas(c, itemView.right + dX, itemView.top.toFloat(), itemView.right.toFloat(), itemView.bottom.toFloat())
|
||||||
|
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dX < 0) {
|
||||||
|
backgroundLeft.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)
|
||||||
|
backgroundLeft.draw(c)
|
||||||
|
} else {
|
||||||
|
backgroundRight.setBounds(itemView.left, itemView.top, itemView.left + dX.toInt(), itemView.bottom)
|
||||||
|
backgroundRight.draw(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearCanvas(c: Canvas?, left: Float, top: Float, right: Float, bottom: Float) {
|
||||||
|
c?.drawRect(left, top, right, bottom, clearPaint)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
|
||||||
|
when (direction) {
|
||||||
|
ItemTouchHelper.LEFT -> eventListener.onItemDeleted(viewHolder.adapterPosition)
|
||||||
|
ItemTouchHelper.RIGHT -> eventListener.onItemArchived(viewHolder.adapterPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EventListener {
|
||||||
|
fun onItemDeleted(position: Int)
|
||||||
|
|
||||||
|
fun onItemArchived(position: Int)
|
||||||
|
|
||||||
|
fun onItemSelected(position: Int)
|
||||||
|
}
|
@ -1,275 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015 Haruki Hasegawa
|
|
||||||
* Copyright 2016 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ch.dissem.apps.abit.adapter
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Typeface
|
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.FrameLayout
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.TextView
|
|
||||||
import ch.dissem.apps.abit.MultiIdenticon
|
|
||||||
import ch.dissem.apps.abit.R
|
|
||||||
import ch.dissem.apps.abit.repository.AndroidLabelRepository.Companion.LABEL_ARCHIVE
|
|
||||||
import ch.dissem.apps.abit.util.Strings.prepareMessageExtract
|
|
||||||
import ch.dissem.bitmessage.entity.Conversation
|
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemAdapter
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstants
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstants.*
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionMoveToSwipedDirection
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionRemoveItem
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractSwipeableItemViewHolder
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.utils.RecyclerViewAdapterUtils
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapted from the basic swipeable example by Haruki Hasegawa. See
|
|
||||||
*
|
|
||||||
* @author Christian Basler
|
|
||||||
* @see [https://github.com/h6ah4i/android-advancedrecyclerview](https://github.com/h6ah4i/android-advancedrecyclerview)
|
|
||||||
*/
|
|
||||||
class SwipeableConversationAdapter(ctx: Context) :
|
|
||||||
RecyclerView.Adapter<SwipeableConversationAdapter.ViewHolder>(),
|
|
||||||
SwipeableItemAdapter<SwipeableConversationAdapter.ViewHolder>, SwipeableItemConstants {
|
|
||||||
|
|
||||||
private val data = LinkedList<Conversation>()
|
|
||||||
var eventListener: EventListener? = null
|
|
||||||
private val itemViewOnClickListener: View.OnClickListener
|
|
||||||
private val swipeableViewContainerOnClickListener: View.OnClickListener
|
|
||||||
|
|
||||||
private var label: Label? = null
|
|
||||||
private var selectedPosition = -1
|
|
||||||
private var activateOnItemClick: Boolean = false
|
|
||||||
|
|
||||||
private val labelUnknown = ctx.getString(R.string.unknown)
|
|
||||||
|
|
||||||
fun setActivateOnItemClick(activateOnItemClick: Boolean) {
|
|
||||||
this.activateOnItemClick = activateOnItemClick
|
|
||||||
}
|
|
||||||
|
|
||||||
interface EventListener {
|
|
||||||
fun onItemDeleted(item: Conversation)
|
|
||||||
|
|
||||||
fun onItemArchived(item: Conversation)
|
|
||||||
|
|
||||||
fun onItemViewClicked(v: View?)
|
|
||||||
}
|
|
||||||
|
|
||||||
class ViewHolder(v: View) : AbstractSwipeableItemViewHolder(v) {
|
|
||||||
val container = v.findViewById<FrameLayout>(R.id.container)!!
|
|
||||||
val avatar = v.findViewById<ImageView>(R.id.avatar)!!
|
|
||||||
val status = v.findViewById<ImageView>(R.id.status)!!
|
|
||||||
val sender = v.findViewById<TextView>(R.id.sender)!!
|
|
||||||
val subject = v.findViewById<TextView>(R.id.subject)!!
|
|
||||||
val extract = v.findViewById<TextView>(R.id.text)!!
|
|
||||||
val count = v.findViewById<TextView>(R.id.count)!!
|
|
||||||
|
|
||||||
override fun getSwipeableContainerView() = container
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
itemViewOnClickListener = View.OnClickListener { view -> onItemViewClick(view) }
|
|
||||||
swipeableViewContainerOnClickListener =
|
|
||||||
View.OnClickListener { view -> onSwipeableViewContainerClick(view) }
|
|
||||||
|
|
||||||
// SwipeableItemAdapter requires stable ID, and also
|
|
||||||
// have to implement the getItemId() method appropriately.
|
|
||||||
setHasStableIds(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun add(item: Conversation) {
|
|
||||||
data.add(item)
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addFirst(item: Conversation) {
|
|
||||||
val index = data.size
|
|
||||||
data.addFirst(item)
|
|
||||||
notifyItemInserted(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addAll(items: Collection<Conversation>) {
|
|
||||||
val index = data.size
|
|
||||||
data.addAll(items)
|
|
||||||
notifyItemRangeInserted(index, items.size)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun remove(item: Conversation) {
|
|
||||||
val index = data.indexOf(item)
|
|
||||||
data.removeAll { it.id == item.id }
|
|
||||||
notifyItemRemoved(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun update(item: Conversation) {
|
|
||||||
val index = data.indexOfFirst { it.id == item.id }
|
|
||||||
if (index >= 0) {
|
|
||||||
data[index] = item
|
|
||||||
notifyItemChanged(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clear(newLabel: Label?) {
|
|
||||||
label = newLabel
|
|
||||||
data.clear()
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onItemViewClick(v: View) {
|
|
||||||
eventListener?.onItemViewClicked(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onSwipeableViewContainerClick(v: View) {
|
|
||||||
eventListener?.onItemViewClicked(
|
|
||||||
RecyclerViewAdapterUtils.getParentViewHolderItemView(v)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getItem(position: Int) = data[position]
|
|
||||||
|
|
||||||
override fun getItemId(position: Int) = data[position].id.leastSignificantBits
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
|
||||||
val inflater = LayoutInflater.from(parent.context)
|
|
||||||
val v = inflater.inflate(R.layout.conversation_row, parent, false)
|
|
||||||
return ViewHolder(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
||||||
val item = data[position]
|
|
||||||
|
|
||||||
holder.apply {
|
|
||||||
if (activateOnItemClick) {
|
|
||||||
container.setBackgroundResource(
|
|
||||||
if (position == selectedPosition)
|
|
||||||
R.drawable.bg_item_selected_state
|
|
||||||
else
|
|
||||||
R.drawable.bg_item_normal_state
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set listeners
|
|
||||||
// (if the item is *pinned*, click event comes to the itemView)
|
|
||||||
itemView.setOnClickListener(itemViewOnClickListener)
|
|
||||||
// (if the item is *not pinned*, click event comes to the container)
|
|
||||||
container.setOnClickListener(swipeableViewContainerOnClickListener)
|
|
||||||
|
|
||||||
// set data
|
|
||||||
avatar.setImageDrawable(MultiIdenticon(item.participants))
|
|
||||||
|
|
||||||
sender.text = item.participants.sortedBy {
|
|
||||||
(it.alias?.let { 0 } ?: 1) + if (it.isChan) 2 else 0
|
|
||||||
}.map { it.alias ?: labelUnknown }.distinct().joinToString()
|
|
||||||
subject.text = prepareMessageExtract(item.subject)
|
|
||||||
extract.text = prepareMessageExtract(item.extract)
|
|
||||||
item.messages.count { it.labels.contains(label) }.let { size ->
|
|
||||||
if (size <= 1) {
|
|
||||||
count.text = ""
|
|
||||||
} else {
|
|
||||||
count.text = size.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (item.hasUnread()) {
|
|
||||||
sender.typeface = Typeface.DEFAULT_BOLD
|
|
||||||
subject.typeface = Typeface.DEFAULT_BOLD
|
|
||||||
} else {
|
|
||||||
sender.typeface = Typeface.DEFAULT
|
|
||||||
subject.typeface = Typeface.DEFAULT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount() = data.size
|
|
||||||
|
|
||||||
override fun onGetSwipeReactionType(holder: ViewHolder, position: Int, x: Int, y: Int): Int =
|
|
||||||
if (label === LABEL_ARCHIVE || label?.type == Label.Type.TRASH) {
|
|
||||||
REACTION_CAN_SWIPE_LEFT or REACTION_CAN_NOT_SWIPE_RIGHT_WITH_RUBBER_BAND_EFFECT
|
|
||||||
} else {
|
|
||||||
REACTION_CAN_SWIPE_BOTH_H
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SwitchIntDef")
|
|
||||||
override fun onSetSwipeBackground(holder: ViewHolder, position: Int, type: Int) =
|
|
||||||
holder.itemView.setBackgroundResource(
|
|
||||||
when (type) {
|
|
||||||
DRAWABLE_SWIPE_NEUTRAL_BACKGROUND -> R.drawable.bg_swipe_item_neutral
|
|
||||||
DRAWABLE_SWIPE_LEFT_BACKGROUND -> R.drawable.bg_swipe_item_left
|
|
||||||
DRAWABLE_SWIPE_RIGHT_BACKGROUND -> if (label === LABEL_ARCHIVE || label?.type == Label.Type.TRASH) {
|
|
||||||
R.drawable.bg_swipe_item_neutral
|
|
||||||
} else {
|
|
||||||
R.drawable.bg_swipe_item_right
|
|
||||||
}
|
|
||||||
else -> R.drawable.bg_swipe_item_neutral
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
@SuppressLint("SwitchIntDef")
|
|
||||||
override fun onSwipeItem(holder: ViewHolder, position: Int, result: Int) =
|
|
||||||
when (result) {
|
|
||||||
RESULT_SWIPED_RIGHT -> SwipeRightResultAction(this, position)
|
|
||||||
RESULT_SWIPED_LEFT -> SwipeLeftResultAction(this, position)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSwipeItemStarted(holder: ViewHolder?, position: Int) = Unit
|
|
||||||
|
|
||||||
fun setSelectedPosition(selectedPosition: Int) {
|
|
||||||
val oldPosition = this.selectedPosition
|
|
||||||
this.selectedPosition = selectedPosition
|
|
||||||
notifyItemChanged(oldPosition)
|
|
||||||
notifyItemChanged(selectedPosition)
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SwipeLeftResultAction internal constructor(
|
|
||||||
adapter: SwipeableConversationAdapter,
|
|
||||||
position: Int
|
|
||||||
) : SwipeResultActionMoveToSwipedDirection() {
|
|
||||||
private var adapter: SwipeableConversationAdapter? = adapter
|
|
||||||
private val item = adapter.data[position]
|
|
||||||
|
|
||||||
override fun onPerformAction() {
|
|
||||||
adapter?.eventListener?.onItemDeleted(item)
|
|
||||||
adapter?.remove(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCleanUp() {
|
|
||||||
adapter = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SwipeRightResultAction internal constructor(
|
|
||||||
adapter: SwipeableConversationAdapter,
|
|
||||||
position: Int
|
|
||||||
) : SwipeResultActionRemoveItem() {
|
|
||||||
private var adapter: SwipeableConversationAdapter? = adapter
|
|
||||||
private val item = adapter.data[position]
|
|
||||||
|
|
||||||
override fun onPerformAction() {
|
|
||||||
adapter?.eventListener?.onItemArchived(item)
|
|
||||||
adapter?.remove(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCleanUp() {
|
|
||||||
adapter = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,262 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2015 Haruki Hasegawa
|
|
||||||
* Copyright 2016 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ch.dissem.apps.abit.adapter
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.graphics.Typeface
|
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.FrameLayout
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.TextView
|
|
||||||
import ch.dissem.apps.abit.Identicon
|
|
||||||
import ch.dissem.apps.abit.R
|
|
||||||
import ch.dissem.apps.abit.repository.AndroidLabelRepository.Companion.LABEL_ARCHIVE
|
|
||||||
import ch.dissem.apps.abit.util.Strings.prepareMessageExtract
|
|
||||||
import ch.dissem.apps.abit.util.getDrawable
|
|
||||||
import ch.dissem.apps.abit.util.getString
|
|
||||||
import ch.dissem.bitmessage.entity.Plaintext
|
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemAdapter
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstants
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstants.*
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionMoveToSwipedDirection
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionRemoveItem
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractSwipeableItemViewHolder
|
|
||||||
import com.h6ah4i.android.widget.advrecyclerview.utils.RecyclerViewAdapterUtils
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapted from the basic swipeable example by Haruki Hasegawa. See
|
|
||||||
*
|
|
||||||
* @author Christian Basler
|
|
||||||
* @see [https://github.com/h6ah4i/android-advancedrecyclerview](https://github.com/h6ah4i/android-advancedrecyclerview)
|
|
||||||
*/
|
|
||||||
class SwipeableMessageAdapter : RecyclerView.Adapter<SwipeableMessageAdapter.ViewHolder>(),
|
|
||||||
SwipeableItemAdapter<SwipeableMessageAdapter.ViewHolder>, SwipeableItemConstants {
|
|
||||||
|
|
||||||
private val data = LinkedList<Plaintext>()
|
|
||||||
var eventListener: EventListener? = null
|
|
||||||
private val itemViewOnClickListener: View.OnClickListener
|
|
||||||
private val swipeableViewContainerOnClickListener: View.OnClickListener
|
|
||||||
|
|
||||||
private var label: Label? = null
|
|
||||||
private var selectedPosition = -1
|
|
||||||
private var activateOnItemClick: Boolean = false
|
|
||||||
|
|
||||||
fun setActivateOnItemClick(activateOnItemClick: Boolean) {
|
|
||||||
this.activateOnItemClick = activateOnItemClick
|
|
||||||
}
|
|
||||||
|
|
||||||
interface EventListener {
|
|
||||||
fun onItemDeleted(item: Plaintext)
|
|
||||||
|
|
||||||
fun onItemArchived(item: Plaintext)
|
|
||||||
|
|
||||||
fun onItemViewClicked(v: View?)
|
|
||||||
}
|
|
||||||
|
|
||||||
class ViewHolder(v: View) : AbstractSwipeableItemViewHolder(v) {
|
|
||||||
val container = v.findViewById<FrameLayout>(R.id.container)!!
|
|
||||||
val avatar = v.findViewById<ImageView>(R.id.avatar)!!
|
|
||||||
val status = v.findViewById<ImageView>(R.id.status)!!
|
|
||||||
val sender = v.findViewById<TextView>(R.id.sender)!!
|
|
||||||
val subject = v.findViewById<TextView>(R.id.subject)!!
|
|
||||||
val extract = v.findViewById<TextView>(R.id.text)!!
|
|
||||||
|
|
||||||
override fun getSwipeableContainerView() = container
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
itemViewOnClickListener = View.OnClickListener { view -> onItemViewClick(view) }
|
|
||||||
swipeableViewContainerOnClickListener =
|
|
||||||
View.OnClickListener { view -> onSwipeableViewContainerClick(view) }
|
|
||||||
|
|
||||||
// SwipeableItemAdapter requires stable ID, and also
|
|
||||||
// have to implement the getItemId() method appropriately.
|
|
||||||
setHasStableIds(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun add(item: Plaintext) {
|
|
||||||
data.add(item)
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addFirst(item: Plaintext) {
|
|
||||||
val index = data.size
|
|
||||||
data.addFirst(item)
|
|
||||||
notifyItemInserted(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addAll(items: Collection<Plaintext>) {
|
|
||||||
val index = data.size
|
|
||||||
data.addAll(items)
|
|
||||||
notifyItemRangeInserted(index, items.size)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun remove(item: Plaintext) {
|
|
||||||
val index = data.indexOf(item)
|
|
||||||
data.removeAll { it.id == item.id }
|
|
||||||
notifyItemRemoved(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun update(item: Plaintext) {
|
|
||||||
val index = data.indexOfFirst { it.id == item.id }
|
|
||||||
if (index >= 0) {
|
|
||||||
data[index] = item
|
|
||||||
notifyItemChanged(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clear(newLabel: Label?) {
|
|
||||||
label = newLabel
|
|
||||||
data.clear()
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onItemViewClick(v: View) {
|
|
||||||
eventListener?.onItemViewClicked(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onSwipeableViewContainerClick(v: View) {
|
|
||||||
eventListener?.onItemViewClicked(
|
|
||||||
RecyclerViewAdapterUtils.getParentViewHolderItemView(v)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getItem(position: Int) = data[position]
|
|
||||||
|
|
||||||
override fun getItemId(position: Int) = data[position].id as Long
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
|
||||||
val inflater = LayoutInflater.from(parent.context)
|
|
||||||
val v = inflater.inflate(R.layout.message_row, parent, false)
|
|
||||||
return ViewHolder(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
||||||
val item = data[position]
|
|
||||||
|
|
||||||
holder.apply {
|
|
||||||
if (activateOnItemClick) {
|
|
||||||
container.setBackgroundResource(
|
|
||||||
if (position == selectedPosition)
|
|
||||||
R.drawable.bg_item_selected_state
|
|
||||||
else
|
|
||||||
R.drawable.bg_item_normal_state
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set listeners
|
|
||||||
// (if the item is *pinned*, click event comes to the itemView)
|
|
||||||
itemView.setOnClickListener(itemViewOnClickListener)
|
|
||||||
// (if the item is *not pinned*, click event comes to the container)
|
|
||||||
container.setOnClickListener(swipeableViewContainerOnClickListener)
|
|
||||||
|
|
||||||
// set data
|
|
||||||
avatar.setImageDrawable(Identicon(item.from))
|
|
||||||
status.setImageResource(item.status.getDrawable())
|
|
||||||
status.contentDescription = holder.status.context.getString(item.status.getString())
|
|
||||||
sender.text = item.from.toString()
|
|
||||||
subject.text = prepareMessageExtract(item.subject)
|
|
||||||
extract.text = prepareMessageExtract(item.text)
|
|
||||||
if (item.isUnread()) {
|
|
||||||
sender.typeface = Typeface.DEFAULT_BOLD
|
|
||||||
subject.typeface = Typeface.DEFAULT_BOLD
|
|
||||||
} else {
|
|
||||||
sender.typeface = Typeface.DEFAULT
|
|
||||||
subject.typeface = Typeface.DEFAULT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount() = data.size
|
|
||||||
|
|
||||||
override fun onGetSwipeReactionType(holder: ViewHolder, position: Int, x: Int, y: Int): Int =
|
|
||||||
if (label === LABEL_ARCHIVE || label?.type == Label.Type.TRASH) {
|
|
||||||
REACTION_CAN_SWIPE_LEFT or REACTION_CAN_NOT_SWIPE_RIGHT_WITH_RUBBER_BAND_EFFECT
|
|
||||||
} else {
|
|
||||||
REACTION_CAN_SWIPE_BOTH_H
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SwitchIntDef")
|
|
||||||
override fun onSetSwipeBackground(holder: ViewHolder, position: Int, type: Int) =
|
|
||||||
holder.itemView.setBackgroundResource(
|
|
||||||
when (type) {
|
|
||||||
DRAWABLE_SWIPE_NEUTRAL_BACKGROUND -> R.drawable.bg_swipe_item_neutral
|
|
||||||
DRAWABLE_SWIPE_LEFT_BACKGROUND -> R.drawable.bg_swipe_item_left
|
|
||||||
DRAWABLE_SWIPE_RIGHT_BACKGROUND -> if (label === LABEL_ARCHIVE || label?.type == Label.Type.TRASH) {
|
|
||||||
R.drawable.bg_swipe_item_neutral
|
|
||||||
} else {
|
|
||||||
R.drawable.bg_swipe_item_right
|
|
||||||
}
|
|
||||||
else -> R.drawable.bg_swipe_item_neutral
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
@SuppressLint("SwitchIntDef")
|
|
||||||
override fun onSwipeItem(holder: ViewHolder, position: Int, result: Int) =
|
|
||||||
when (result) {
|
|
||||||
RESULT_SWIPED_RIGHT -> SwipeRightResultAction(this, position)
|
|
||||||
RESULT_SWIPED_LEFT -> SwipeLeftResultAction(this, position)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSwipeItemStarted(holder: ViewHolder?, position: Int) = Unit
|
|
||||||
|
|
||||||
fun setSelectedPosition(selectedPosition: Int) {
|
|
||||||
val oldPosition = this.selectedPosition
|
|
||||||
this.selectedPosition = selectedPosition
|
|
||||||
notifyItemChanged(oldPosition)
|
|
||||||
notifyItemChanged(selectedPosition)
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SwipeLeftResultAction internal constructor(
|
|
||||||
adapter: SwipeableMessageAdapter,
|
|
||||||
position: Int
|
|
||||||
) : SwipeResultActionMoveToSwipedDirection() {
|
|
||||||
private var adapter: SwipeableMessageAdapter? = adapter
|
|
||||||
private val item = adapter.data[position]
|
|
||||||
|
|
||||||
override fun onPerformAction() {
|
|
||||||
adapter?.eventListener?.onItemDeleted(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCleanUp() {
|
|
||||||
adapter = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SwipeRightResultAction internal constructor(
|
|
||||||
adapter: SwipeableMessageAdapter,
|
|
||||||
position: Int
|
|
||||||
) : SwipeResultActionRemoveItem() {
|
|
||||||
private var adapter: SwipeableMessageAdapter? = adapter
|
|
||||||
private val item = adapter.data[position]
|
|
||||||
|
|
||||||
override fun onPerformAction() {
|
|
||||||
adapter?.eventListener?.onItemArchived(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCleanUp() {
|
|
||||||
adapter = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,12 +19,12 @@ package ch.dissem.apps.abit.dialog
|
|||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v7.app.AppCompatDialogFragment
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatDialogFragment
|
||||||
import ch.dissem.apps.abit.ImportIdentityActivity
|
import ch.dissem.apps.abit.ImportIdentityActivity
|
||||||
import ch.dissem.apps.abit.MainActivity
|
import ch.dissem.apps.abit.MainActivity
|
||||||
import ch.dissem.apps.abit.R
|
import ch.dissem.apps.abit.R
|
||||||
@ -33,7 +33,7 @@ import ch.dissem.bitmessage.BitmessageContext
|
|||||||
import ch.dissem.bitmessage.entity.payload.Pubkey
|
import ch.dissem.bitmessage.entity.payload.Pubkey
|
||||||
import kotlinx.android.synthetic.main.dialog_add_identity.*
|
import kotlinx.android.synthetic.main.dialog_add_identity.*
|
||||||
import org.jetbrains.anko.doAsync
|
import org.jetbrains.anko.doAsync
|
||||||
import org.jetbrains.anko.support.v4.startActivity
|
import org.jetbrains.anko.startActivity
|
||||||
import org.jetbrains.anko.uiThread
|
import org.jetbrains.anko.uiThread
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +77,7 @@ class AddIdentityDialogFragment : AppCompatDialogFragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
R.id.import_identity -> startActivity<ImportIdentityActivity>()
|
R.id.import_identity -> ctx.startActivity<ImportIdentityActivity>()
|
||||||
R.id.add_chan -> addChanDialog()
|
R.id.add_chan -> addChanDialog()
|
||||||
R.id.add_deterministic_address -> DeterministicIdentityDialogFragment().show(fragmentManager, "dialog")
|
R.id.add_deterministic_address -> DeterministicIdentityDialogFragment().show(fragmentManager, "dialog")
|
||||||
else -> return@OnClickListener
|
else -> return@OnClickListener
|
||||||
|
@ -18,7 +18,7 @@ package ch.dissem.apps.abit.dialog
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v7.app.AppCompatDialogFragment
|
import androidx.appcompat.app.AppCompatDialogFragment
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -19,7 +19,7 @@ package ch.dissem.apps.abit.dialog
|
|||||||
import android.app.Activity.RESULT_OK
|
import android.app.Activity.RESULT_OK
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v7.app.AppCompatDialogFragment
|
import androidx.appcompat.app.AppCompatDialogFragment
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -2,7 +2,7 @@ package ch.dissem.apps.abit.drawer
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.support.v4.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import android.widget.Toast.LENGTH_LONG
|
import android.widget.Toast.LENGTH_LONG
|
||||||
|
@ -21,8 +21,8 @@ import android.app.NotificationChannel
|
|||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.support.annotation.ColorRes
|
import androidx.annotation.ColorRes
|
||||||
import android.support.v4.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import ch.dissem.apps.abit.R
|
import ch.dissem.apps.abit.R
|
||||||
import org.jetbrains.anko.notificationManager
|
import org.jetbrains.anko.notificationManager
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
package ch.dissem.apps.abit.notification
|
package ch.dissem.apps.abit.notification
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.support.v4.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import ch.dissem.apps.abit.R
|
import ch.dissem.apps.abit.R
|
||||||
import ch.dissem.apps.abit.service.Job
|
import ch.dissem.apps.abit.service.Job
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
package ch.dissem.apps.abit.notification
|
package ch.dissem.apps.abit.notification
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.support.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import android.support.v4.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
|
|
||||||
import ch.dissem.apps.abit.R
|
import ch.dissem.apps.abit.R
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import android.app.PendingIntent
|
|||||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.support.v4.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import ch.dissem.apps.abit.MainActivity
|
import ch.dissem.apps.abit.MainActivity
|
||||||
import ch.dissem.apps.abit.R
|
import ch.dissem.apps.abit.R
|
||||||
import ch.dissem.apps.abit.service.BitmessageIntentService
|
import ch.dissem.apps.abit.service.BitmessageIntentService
|
||||||
|
@ -21,9 +21,9 @@ import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.support.v4.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import android.support.v4.app.NotificationCompat.BigTextStyle
|
import androidx.core.app.NotificationCompat.BigTextStyle
|
||||||
import android.support.v4.app.NotificationCompat.InboxStyle
|
import androidx.core.app.NotificationCompat.InboxStyle
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
|
@ -19,7 +19,7 @@ package ch.dissem.apps.abit.notification
|
|||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.support.v4.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
|
|
||||||
import ch.dissem.apps.abit.MainActivity
|
import ch.dissem.apps.abit.MainActivity
|
||||||
import ch.dissem.apps.abit.R
|
import ch.dissem.apps.abit.R
|
||||||
|
@ -176,7 +176,7 @@ class AndroidMessageRepository(private val sql: SqlHelper, private val prefs: Pr
|
|||||||
|
|
||||||
override fun find(where: String, offset: Int, limit: Int) = find(where, offset, limit, false)
|
override fun find(where: String, offset: Int, limit: Int) = find(where, offset, limit, false)
|
||||||
|
|
||||||
fun find(where: String, offset: Int, limit: Int, separateIdentities: Boolean): List<Plaintext> {
|
private fun find(where: String, offset: Int, limit: Int, separateIdentities: Boolean): List<Plaintext> {
|
||||||
val result = LinkedList<Plaintext>()
|
val result = LinkedList<Plaintext>()
|
||||||
val (selectIdentityQuery, selectIdentityArgs) = getSelectIdentity(separateIdentities)
|
val (selectIdentityQuery, selectIdentityArgs) = getSelectIdentity(separateIdentities)
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ package ch.dissem.apps.abit.service
|
|||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Binder
|
import android.os.Binder
|
||||||
import android.support.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import android.support.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import android.support.v4.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import ch.dissem.apps.abit.notification.BatchNotification
|
import ch.dissem.apps.abit.notification.BatchNotification
|
||||||
import ch.dissem.apps.abit.notification.BatchNotification.Companion.ONGOING_NOTIFICATION_ID
|
import ch.dissem.apps.abit.notification.BatchNotification.Companion.ONGOING_NOTIFICATION_ID
|
||||||
import org.jetbrains.anko.doAsync
|
import org.jetbrains.anko.doAsync
|
||||||
|
@ -48,6 +48,7 @@ class NodeStartupService : JobService() {
|
|||||||
addAction(Intent.ACTION_BATTERY_CHANGED)
|
addAction(Intent.ACTION_BATTERY_CHANGED)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
startForeground(0, notification.notification)
|
||||||
NodeStartupService.running = false
|
NodeStartupService.running = false
|
||||||
|
|
||||||
if (!isRunning) {
|
if (!isRunning) {
|
||||||
|
@ -19,7 +19,7 @@ package ch.dissem.apps.abit.service
|
|||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Binder
|
import android.os.Binder
|
||||||
import android.support.v4.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import ch.dissem.apps.abit.notification.ProofOfWorkNotification
|
import ch.dissem.apps.abit.notification.ProofOfWorkNotification
|
||||||
import ch.dissem.apps.abit.notification.ProofOfWorkNotification.Companion.ONGOING_NOTIFICATION_ID
|
import ch.dissem.apps.abit.notification.ProofOfWorkNotification.Companion.ONGOING_NOTIFICATION_ID
|
||||||
import ch.dissem.apps.abit.util.PowStats
|
import ch.dissem.apps.abit.util.PowStats
|
||||||
|
@ -23,19 +23,18 @@ import ch.dissem.apps.abit.R
|
|||||||
import ch.dissem.apps.abit.adapter.SwipeableMessageAdapter
|
import ch.dissem.apps.abit.adapter.SwipeableMessageAdapter
|
||||||
import ch.dissem.apps.abit.listener.MessageListener
|
import ch.dissem.apps.abit.listener.MessageListener
|
||||||
import ch.dissem.apps.abit.repository.*
|
import ch.dissem.apps.abit.repository.*
|
||||||
import ch.dissem.apps.abit.util.Observable
|
|
||||||
import ch.dissem.apps.abit.util.preferences
|
import ch.dissem.apps.abit.util.preferences
|
||||||
import ch.dissem.bitmessage.BitmessageContext
|
import ch.dissem.bitmessage.BitmessageContext
|
||||||
import ch.dissem.bitmessage.cryptography.sc.SpongyCryptography
|
import ch.dissem.bitmessage.cryptography.sc.SpongyCryptography
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||||
import ch.dissem.bitmessage.entity.payload.Pubkey
|
import ch.dissem.bitmessage.entity.payload.Pubkey
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||||
import ch.dissem.bitmessage.factory.BufferPool
|
|
||||||
import ch.dissem.bitmessage.networking.nio.NioNetworkHandler
|
import ch.dissem.bitmessage.networking.nio.NioNetworkHandler
|
||||||
import ch.dissem.bitmessage.ports.DefaultLabeler
|
import ch.dissem.bitmessage.ports.DefaultLabeler
|
||||||
import ch.dissem.bitmessage.utils.ConversationService
|
import ch.dissem.bitmessage.utils.ConversationService
|
||||||
import ch.dissem.bitmessage.utils.TTL
|
import ch.dissem.bitmessage.utils.TTL
|
||||||
import ch.dissem.bitmessage.utils.UnixTime.DAY
|
import ch.dissem.bitmessage.utils.UnixTime.DAY
|
||||||
|
import io.reactivex.subjects.BehaviorSubject
|
||||||
import org.jetbrains.anko.doAsync
|
import org.jetbrains.anko.doAsync
|
||||||
import org.jetbrains.anko.uiThread
|
import org.jetbrains.anko.uiThread
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
@ -44,7 +43,7 @@ import java.lang.ref.WeakReference
|
|||||||
* Provides singleton objects across the application.
|
* Provides singleton objects across the application.
|
||||||
*/
|
*/
|
||||||
object Singleton {
|
object Singleton {
|
||||||
var currentLabel = Observable<Label?>(null)
|
var currentLabel = BehaviorSubject.create<Label>()
|
||||||
|
|
||||||
private var swipeableMessageAdapter: WeakReference<SwipeableMessageAdapter>? = null
|
private var swipeableMessageAdapter: WeakReference<SwipeableMessageAdapter>? = null
|
||||||
val labeler = DefaultLabeler().apply {
|
val labeler = DefaultLabeler().apply {
|
||||||
@ -52,7 +51,7 @@ object Singleton {
|
|||||||
MainActivity.apply {
|
MainActivity.apply {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
swipeableMessageAdapter?.get()?.let { swipeableMessageAdapter ->
|
swipeableMessageAdapter?.get()?.let { swipeableMessageAdapter ->
|
||||||
currentLabel.value?.let { label ->
|
currentLabel.value?.let {label ->
|
||||||
when {
|
when {
|
||||||
label.type == Label.Type.TRASH
|
label.type == Label.Type.TRASH
|
||||||
&& added.all { it.type == Label.Type.TRASH }
|
&& added.all { it.type == Label.Type.TRASH }
|
||||||
@ -100,7 +99,6 @@ object Singleton {
|
|||||||
|
|
||||||
fun getBitmessageContext(context: Context): BitmessageContext =
|
fun getBitmessageContext(context: Context): BitmessageContext =
|
||||||
init({ bitmessageContext }, { bitmessageContext = it }) {
|
init({ bitmessageContext }, { bitmessageContext = it }) {
|
||||||
BufferPool.setLimit(4)
|
|
||||||
BitmessageContext.build {
|
BitmessageContext.build {
|
||||||
TTL.pubkey = 2 * DAY
|
TTL.pubkey = 2 * DAY
|
||||||
val ctx = context.applicationContext
|
val ctx = context.applicationContext
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package ch.dissem.apps.abit.util
|
package ch.dissem.apps.abit.util
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.support.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import ch.dissem.apps.abit.R
|
import ch.dissem.apps.abit.R
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||||
import com.mikepenz.community_material_typeface_library.CommunityMaterial
|
import com.mikepenz.community_material_typeface_library.CommunityMaterial
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
package ch.dissem.apps.abit.util
|
|
||||||
|
|
||||||
import kotlin.properties.Delegates
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple observable implementation that should be mostly
|
|
||||||
*/
|
|
||||||
class Observable<T>(value: T) {
|
|
||||||
private val observers = mutableMapOf<Any, (T) -> Unit>()
|
|
||||||
|
|
||||||
var value: T by Delegates.observable(value) { _, old, new ->
|
|
||||||
if (old != new) {
|
|
||||||
observers.values.forEach { it.invoke(new) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The key will make sure the observer can easily be removed. Usually the key should be either
|
|
||||||
* the object that created the observer, or the observer itself, if it's easily available.
|
|
||||||
*
|
|
||||||
* Note that a map is used for observers, so if you define more than one observer with the same
|
|
||||||
* key, all previous ones will be removed. Also, the observers will be notified in no specific
|
|
||||||
* order.
|
|
||||||
*
|
|
||||||
* To prevent memory leaks, the observer must be removed if it isn't used anymore.
|
|
||||||
*/
|
|
||||||
fun addObserver(key: Any, observer: (T) -> Unit) {
|
|
||||||
observers[key] = observer
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the observer that was registered with the given key.
|
|
||||||
*/
|
|
||||||
fun removeObserver(key: Any) {
|
|
||||||
observers.remove(key)
|
|
||||||
}
|
|
||||||
}
|
|
@ -57,7 +57,7 @@ class Preferences internal constructor(private val ctx: Context) {
|
|||||||
ctx.batteryManager.isCharging
|
ctx.batteryManager.isCharging
|
||||||
} else {
|
} else {
|
||||||
val intent = ctx.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
val intent = ctx.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||||
val status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
|
val status = intent?.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
|
||||||
status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL
|
status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
app/src/main/res/drawable/ic_battery_charging.xml
Normal file
13
app/src/main/res/drawable/ic_battery_charging.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33V8h5.47L13,7v1h4V5.33C17,4.6 16.4,4 15.67,4z"
|
||||||
|
android:fillAlpha=".3"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M13,12.5h2L11,20v-5.5H9L12.47,8H7v12.67C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V8h-4v4.5z"/>
|
||||||
|
</vector>
|
8
app/src/main/res/drawable/ic_broom.xml
Normal file
8
app/src/main/res/drawable/ic_broom.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<!-- drawable/broom.xml -->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#000" android:pathData="M19.36,2.72L20.78,4.14L15.06,9.85C16.13,11.39 16.28,13.24 15.38,14.44L9.06,8.12C10.26,7.22 12.11,7.37 13.65,8.44L19.36,2.72M5.93,17.57C3.92,15.56 2.69,13.16 2.35,10.92L7.23,8.83L14.67,16.27L12.58,21.15C10.34,20.81 7.94,19.58 5.93,17.57Z" />
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/ic_bug_report.xml
Normal file
9
app/src/main/res/drawable/ic_bug_report.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M20,8h-2.81c-0.45,-0.78 -1.07,-1.45 -1.82,-1.96L17,4.41 15.59,3l-2.17,2.17C12.96,5.06 12.49,5 12,5c-0.49,0 -0.96,0.06 -1.41,0.17L8.41,3 7,4.41l1.62,1.63C7.88,6.55 7.26,7.22 6.81,8L4,8v2h2.09c-0.05,0.33 -0.09,0.66 -0.09,1v1L4,12v2h2v1c0,0.34 0.04,0.67 0.09,1L4,16v2h2.81c1.04,1.79 2.97,3 5.19,3s4.15,-1.21 5.19,-3L20,18v-2h-2.09c0.05,-0.33 0.09,-0.66 0.09,-1v-1h2v-2h-2v-1c0,-0.34 -0.04,-0.67 -0.09,-1L20,10L20,8zM14,16h-4v-2h4v2zM14,12h-4v-2h4v2z"/>
|
||||||
|
</vector>
|
8
app/src/main/res/drawable/ic_check_all.xml
Normal file
8
app/src/main/res/drawable/ic_check_all.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<!-- drawable/check_all.xml -->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path android:fillColor="#000" android:pathData="M0.41,13.41L6,19L7.41,17.58L1.83,12M22.24,5.58L11.66,16.17L7.5,12L6.07,13.41L11.66,19L23.66,7M18,7L16.59,5.58L10.24,11.93L11.66,13.34L18,7Z" />
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/ic_emulate_conversations.xml
Normal file
9
app/src/main/res/drawable/ic_emulate_conversations.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM8,14L6,14v-2h2v2zM8,11L6,11L6,9h2v2zM8,8L6,8L6,6h2v2zM15,14h-5v-2h5v2zM18,11h-8L10,9h8v2zM18,8h-8L10,6h8v2z"/>
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/ic_export.xml
Normal file
9
app/src/main/res/drawable/ic_export.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M9,16h6v-6h4l-7,-7 -7,7h4zM5,18h14v2L5,20z"/>
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/ic_import.xml
Normal file
9
app/src/main/res/drawable/ic_import.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z"/>
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/ic_info.xml
Normal file
9
app/src/main/res/drawable/ic_info.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
|
||||||
|
</vector>
|
13
app/src/main/res/drawable/ic_network_wifi.xml
Normal file
13
app/src/main/res/drawable/ic_network_wifi.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12.01,21.49L23.64,7c-0.45,-0.34 -4.93,-4 -11.64,-4C5.28,3 0.81,6.66 0.36,7l11.63,14.49 0.01,0.01 0.01,-0.01z"
|
||||||
|
android:fillAlpha=".3"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M3.53,10.95l8.46,10.54 0.01,0.01 0.01,-0.01 8.46,-10.54C20.04,10.62 16.81,8 12,8c-4.81,0 -8.04,2.62 -8.47,2.95z"/>
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/ic_port.xml
Normal file
9
app/src/main/res/drawable/ic_port.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M7.77,6.76L6.23,5.48 0.82,12l5.41,6.52 1.54,-1.28L3.42,12l4.35,-5.24zM7,13h2v-2L7,11v2zM17,11h-2v2h2v-2zM11,13h2v-2h-2v2zM17.77,5.48l-1.54,1.28L20.58,12l-4.35,5.24 1.54,1.28L23.18,12l-5.41,-6.52z"/>
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/ic_separate_identities.xml
Normal file
9
app/src/main/res/drawable/ic_separate_identities.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M16,11c1.66,0 2.99,-1.34 2.99,-3S17.66,5 16,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zM8,11c1.66,0 2.99,-1.34 2.99,-3S9.66,5 8,5C6.34,5 5,6.34 5,8s1.34,3 3,3zM8,13c-2.33,0 -7,1.17 -7,3.5L1,19h14v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5zM16,13c-0.29,0 -0.62,0.02 -0.97,0.05 1.16,0.84 1.97,1.97 1.97,3.45L17,19h6v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5z"/>
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/ic_support_app.xml
Normal file
9
app/src/main/res/drawable/ic_support_app.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M9,11.24L9,7.5C9,6.12 10.12,5 11.5,5S14,6.12 14,7.5v3.74c1.21,-0.81 2,-2.18 2,-3.74C16,5.01 13.99,3 11.5,3S7,5.01 7,7.5c0,1.56 0.79,2.93 2,3.74zM18.84,15.87l-4.54,-2.26c-0.17,-0.07 -0.35,-0.11 -0.54,-0.11L13,13.5v-6c0,-0.83 -0.67,-1.5 -1.5,-1.5S10,6.67 10,7.5v10.74l-3.43,-0.72c-0.08,-0.01 -0.15,-0.03 -0.24,-0.03 -0.31,0 -0.59,0.13 -0.79,0.33l-0.79,0.8 4.94,4.94c0.27,0.27 0.65,0.44 1.06,0.44h6.79c0.75,0 1.33,-0.55 1.44,-1.28l0.75,-5.27c0.01,-0.07 0.02,-0.14 0.02,-0.2 0,-0.62 -0.38,-1.16 -0.91,-1.38z"/>
|
||||||
|
</vector>
|
@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
Copyright (C) 2015 Haruki Hasegawa
|
|
||||||
|
|
||||||
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.
|
|
||||||
-->
|
|
||||||
<shape
|
|
||||||
android:shape="rectangle"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<size android:height="1px"/>
|
|
||||||
<solid android:color="@color/divider"/>
|
|
||||||
</shape>
|
|
@ -1,11 +1,11 @@
|
|||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center">
|
android:gravity="center">
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="64dp"
|
android:layout_height="64dp"
|
||||||
@ -19,7 +19,7 @@
|
|||||||
tools:ignore="UnusedAttribute"
|
tools:ignore="UnusedAttribute"
|
||||||
tools:layout_editor_absoluteX="0dp" />
|
tools:layout_editor_absoluteX="0dp" />
|
||||||
|
|
||||||
<android.support.constraint.Guideline
|
<androidx.constraintlayout.widget.Guideline
|
||||||
android:id="@+id/guideline"
|
android:id="@+id/guideline"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -74,4 +74,4 @@
|
|||||||
tools:ignore="UnusedAttribute"
|
tools:ignore="UnusedAttribute"
|
||||||
tools:layout_editor_absoluteX="8dp" />
|
tools:layout_editor_absoluteX="8dp" />
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="24dp">
|
android:padding="24dp">
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/address_wrapper"
|
android:id="@+id/address_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -17,16 +17,17 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/address"
|
android:hint="@string/address"
|
||||||
|
android:importantForAutofill="no"
|
||||||
android:inputType="textNoSuggestions" />
|
android:inputType="textNoSuggestions" />
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/label_wrapper"
|
android:id="@+id/label_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignStart="@+id/address_wrapper"
|
|
||||||
android:layout_below="@+id/address_wrapper"
|
android:layout_below="@+id/address_wrapper"
|
||||||
|
android:layout_alignStart="@+id/address_wrapper"
|
||||||
android:layout_marginTop="16dp">
|
android:layout_marginTop="16dp">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
@ -34,18 +35,19 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/label"
|
android:hint="@string/label"
|
||||||
|
android:importantForAutofill="no"
|
||||||
android:inputType="textPersonName" />
|
android:inputType="textPersonName" />
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/subscribe"
|
android:id="@+id/subscribe"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignStart="@+id/address_wrapper"
|
|
||||||
android:layout_below="@+id/label_wrapper"
|
android:layout_below="@+id/label_wrapper"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_alignStart="@+id/address_wrapper"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
android:text="@string/subscribe" />
|
android:text="@string/subscribe" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@ -53,10 +55,10 @@
|
|||||||
style="?android:attr/borderlessButtonStyle"
|
style="?android:attr/borderlessButtonStyle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_below="@+id/subscribe"
|
android:layout_below="@+id/subscribe"
|
||||||
android:layout_marginBottom="12dp"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
android:text="@string/do_import" />
|
android:text="@string/do_import" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center">
|
android:gravity="center">
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
android:textSize="10dp"
|
android:textSize="10dp"
|
||||||
tools:ignore="SpUsage" />
|
tools:ignore="SpUsage" />
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/label_wrapper"
|
android:id="@+id/label_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -27,9 +27,10 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/label"
|
android:hint="@string/label"
|
||||||
|
android:importantForAutofill="no"
|
||||||
android:inputType="textPersonName" />
|
android:inputType="textPersonName" />
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/subscribe"
|
android:id="@+id/subscribe"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.design.widget.CoordinatorLayout
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
@ -19,11 +19,11 @@
|
|||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
</TextView>
|
</TextView>
|
||||||
|
|
||||||
<android.support.design.widget.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
@ -36,6 +36,6 @@
|
|||||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
||||||
tools:ignore="UnusedAttribute"/>
|
tools:ignore="UnusedAttribute"/>
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
@ -14,15 +14,15 @@
|
|||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingBottom="18dp"
|
|
||||||
android:paddingEnd="24dp"
|
|
||||||
android:paddingStart="24dp"
|
android:paddingStart="24dp"
|
||||||
android:paddingTop="18dp">
|
android:paddingTop="18dp"
|
||||||
|
android:paddingEnd="24dp"
|
||||||
|
android:paddingBottom="18dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/description"
|
android:id="@+id/description"
|
||||||
@ -34,7 +34,7 @@
|
|||||||
tools:layout_constraintLeft_creator="1"
|
tools:layout_constraintLeft_creator="1"
|
||||||
tools:layout_constraintTop_creator="1" />
|
tools:layout_constraintTop_creator="1" />
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/label_wrapper"
|
android:id="@+id/label_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -47,11 +47,12 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/label"
|
android:hint="@string/label"
|
||||||
|
android:autofillHints="label"
|
||||||
android:inputType="text" />
|
android:inputType="text" />
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/passphrase_wrapper"
|
android:id="@+id/passphrase_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -63,11 +64,12 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/passphrase"
|
android:hint="@string/passphrase"
|
||||||
|
android:autofillHints="passphrase"
|
||||||
android:inputType="textMultiLine" />
|
android:inputType="textMultiLine" />
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/number_of_identities_wrapper"
|
android:id="@+id/number_of_identities_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -80,11 +82,12 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
android:hint="@string/number_of_identities"
|
android:hint="@string/number_of_identities"
|
||||||
|
android:autofillHints="numberOfIdentities"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
android:text="1"
|
android:text="1"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/shorter"
|
android:id="@+id/shorter"
|
||||||
@ -115,4 +118,4 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="@id/ok"
|
app:layout_constraintBottom_toBottomOf="@id/ok"
|
||||||
app:layout_constraintRight_toLeftOf="@id/ok" />
|
app:layout_constraintRight_toLeftOf="@id/ok" />
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
@ -98,4 +98,4 @@
|
|||||||
android:textColor="@color/colorAccent"
|
android:textColor="@color/colorAccent"
|
||||||
app:layout_constraintRight_toLeftOf="@+id/ok"
|
app:layout_constraintRight_toLeftOf="@+id/ok"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/radioGroup"/>
|
app:layout_constraintTop_toBottomOf="@+id/radioGroup"/>
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
@ -56,4 +56,4 @@
|
|||||||
app:layout_constraintEnd_toEndOf="@id/description"
|
app:layout_constraintEnd_toEndOf="@id/description"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/ok"
|
app:layout_constraintTop_toBottomOf="@+id/ok"
|
||||||
tools:layout_editor_absoluteX="8dp"/>
|
tools:layout_editor_absoluteX="8dp"/>
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
@ -14,5 +14,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:hint="@string/passphrase"
|
android:hint="@string/passphrase"
|
||||||
|
android:autofillHints="passphrase"
|
||||||
android:inputType="textMultiLine"/>
|
android:inputType="textMultiLine"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
<!--
|
|
||||||
~ Copyright 2015 Christian Basler
|
~ Copyright 2015 Christian Basler
|
||||||
~
|
~
|
||||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -28,19 +27,20 @@
|
|||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:src="@color/colorAccent"
|
android:src="@color/colorAccent"
|
||||||
tools:ignore="ContentDescription"/>
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/name"
|
android:id="@+id/name"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignTop="@+id/avatar"
|
android:layout_alignTop="@+id/avatar"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_toEndOf="@+id/avatar"
|
android:layout_toEndOf="@+id/avatar"
|
||||||
|
android:importantForAutofill="no"
|
||||||
android:inputType="textPersonName"
|
android:inputType="textPersonName"
|
||||||
android:text=""
|
android:text=""
|
||||||
tools:ignore="LabelFor"/>
|
tools:ignore="LabelFor" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/address"
|
android:id="@+id/address"
|
||||||
@ -52,7 +52,7 @@
|
|||||||
android:paddingRight="16dp"
|
android:paddingRight="16dp"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
tools:text="BM-XyYxXyYxXyYxXyYxXyYx"/>
|
tools:text="BM-XyYxXyYxXyYxXyYxXyYx" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/stream_number"
|
android:id="@+id/stream_number"
|
||||||
@ -64,7 +64,7 @@
|
|||||||
android:paddingLeft="16dp"
|
android:paddingLeft="16dp"
|
||||||
android:paddingRight="16dp"
|
android:paddingRight="16dp"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
tools:text="Stream #"/>
|
tools:text="Stream #" />
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/active"
|
android:id="@+id/active"
|
||||||
@ -72,21 +72,21 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/stream_number"
|
android:layout_below="@+id/stream_number"
|
||||||
android:paddingLeft="16dp"
|
android:paddingLeft="16dp"
|
||||||
android:paddingRight="16dp"
|
|
||||||
android:paddingTop="16dp"
|
android:paddingTop="16dp"
|
||||||
android:text="@string/subscribed"/>
|
android:paddingRight="16dp"
|
||||||
|
android:text="@string/subscribed" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/pubkey_available"
|
android:id="@+id/pubkey_available"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_below="@+id/active"
|
android:layout_below="@+id/active"
|
||||||
android:paddingEnd="4dp"
|
android:layout_alignParentStart="true"
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingTop="16dp"
|
android:paddingTop="16dp"
|
||||||
|
android:paddingEnd="4dp"
|
||||||
android:src="@drawable/public_key"
|
android:src="@drawable/public_key"
|
||||||
tools:ignore="ContentDescription"/>
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/pubkey_available_desc"
|
android:id="@+id/pubkey_available_desc"
|
||||||
@ -95,25 +95,25 @@
|
|||||||
android:layout_alignBottom="@id/pubkey_available"
|
android:layout_alignBottom="@id/pubkey_available"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_toEndOf="@id/pubkey_available"
|
android:layout_toEndOf="@id/pubkey_available"
|
||||||
android:paddingEnd="16dp"
|
|
||||||
android:paddingStart="0dp"
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
android:text="@string/pubkey_available"
|
android:text="@string/pubkey_available"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/qr_code"
|
android:id="@+id/qr_code"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_below="@+id/pubkey_available"
|
android:layout_below="@+id/pubkey_available"
|
||||||
android:layout_marginBottom="64dp"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginBottom="64dp"
|
||||||
android:contentDescription="@string/alt_qr_code"
|
android:contentDescription="@string/alt_qr_code"
|
||||||
android:elevation="2dp"
|
android:elevation="2dp"
|
||||||
tools:ignore="UnusedAttribute"
|
tools:ignore="UnusedAttribute"
|
||||||
tools:src="@drawable/public_key"/>
|
tools:src="@drawable/public_key" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@id/android:list"
|
android:id="@android:id/list"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="4dp">
|
android:paddingTop="4dp">
|
||||||
@ -33,13 +33,14 @@
|
|||||||
android:id="@+id/recipient_input"
|
android:id="@+id/recipient_input"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:autofillHints="bitmessageAddress"
|
||||||
android:hint="@string/to"
|
android:hint="@string/to"
|
||||||
android:inputType="textNoSuggestions"
|
android:inputType="textNoSuggestions"
|
||||||
android:maxLines="1" />
|
android:maxLines="1" />
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
@ -47,17 +48,19 @@
|
|||||||
android:id="@+id/subject_input"
|
android:id="@+id/subject_input"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:autofillHints="subject"
|
||||||
android:hint="@string/subject"
|
android:hint="@string/subject"
|
||||||
android:inputType="textEmailSubject"
|
android:inputType="textEmailSubject"
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/body_input"
|
android:id="@+id/body_input"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:autofillHints="body, message"
|
||||||
android:gravity="start|top"
|
android:gravity="start|top"
|
||||||
android:hint="@string/compose_body_hint"
|
android:hint="@string/compose_body_hint"
|
||||||
android:inputType="textMultiLine|textCapSentences"
|
android:inputType="textMultiLine|textCapSentences"
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
android:layout_below="@id/subject"
|
android:layout_below="@id/subject"
|
||||||
android:background="@color/divider" />
|
android:background="@color/divider" />
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/messages"
|
android:id="@+id/messages"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -41,6 +41,7 @@
|
|||||||
android:gravity="start|top"
|
android:gravity="start|top"
|
||||||
android:hint="@string/wif_string"
|
android:hint="@string/wif_string"
|
||||||
android:inputType="textMultiLine|text"
|
android:inputType="textMultiLine|text"
|
||||||
|
android:autofillHints="wif, comment, data"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/next"
|
app:layout_constraintBottom_toTopOf="@+id/next"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
@ -57,4 +58,4 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"/>
|
app:layout_constraintRight_toRightOf="parent"/>
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -33,7 +33,7 @@
|
|||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
@ -55,4 +55,4 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"/>
|
app:layout_constraintRight_toRightOf="parent"/>
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
android:paddingRight="8dp"
|
android:paddingRight="8dp"
|
||||||
tools:text="Recipient" />
|
tools:text="Recipient" />
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/parents"
|
android:id="@+id/parents"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -99,7 +99,7 @@
|
|||||||
tools:text="Message Body"
|
tools:text="Message Body"
|
||||||
android:textIsSelectable="true" />
|
android:textIsSelectable="true" />
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/labels"
|
android:id="@+id/labels"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -108,7 +108,7 @@
|
|||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:layout_marginBottom="16dp"/>
|
android:layout_marginBottom="16dp"/>
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/responses"
|
android:id="@+id/responses"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
tools:text="Message Body" />
|
tools:text="Message Body" />
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/labels"
|
android:id="@+id/labels"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -16,11 +16,11 @@
|
|||||||
tools:context=".ComposeMessageActivity"
|
tools:context=".ComposeMessageActivity"
|
||||||
tools:layout="@layout/fragment_compose_message"/>
|
tools:layout="@layout/fragment_compose_message"/>
|
||||||
|
|
||||||
<android.support.design.widget.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
@ -30,7 +30,7 @@
|
|||||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
||||||
tools:ignore="UnusedAttribute"/>
|
tools:ignore="UnusedAttribute"/>
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -16,11 +16,11 @@
|
|||||||
tools:context=".ComposeMessageActivity"
|
tools:context=".ComposeMessageActivity"
|
||||||
tools:layout="@layout/fragment_compose_message"/>
|
tools:layout="@layout/fragment_compose_message"/>
|
||||||
|
|
||||||
<android.support.design.widget.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
@ -31,7 +31,7 @@
|
|||||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
||||||
tools:ignore="UnusedAttribute"/>
|
tools:ignore="UnusedAttribute"/>
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
@ -141,9 +141,8 @@ Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfigu
|
|||||||
<string name="emulate_conversations_initialize">Bestehende Nachrichten nach Betreff gruppieren</string>
|
<string name="emulate_conversations_initialize">Bestehende Nachrichten nach Betreff gruppieren</string>
|
||||||
<string name="preference_group_advanced">Erweitert</string>
|
<string name="preference_group_advanced">Erweitert</string>
|
||||||
<string name="preference_group_network_and_performance">Netzwerk & Performanz</string>
|
<string name="preference_group_network_and_performance">Netzwerk & Performanz</string>
|
||||||
<string name="preference_group_network_and_performance_summary">Feineinstellungen für Netzwerk und Protokoll-Details</string>
|
|
||||||
<string name="preference_group_user_experience">Verhalten</string>
|
<string name="preference_group_user_experience">Verhalten</string>
|
||||||
<string name="preference_group_user_experience_summary">Ändern, wie Nachrichten dargestellt werden</string>
|
<string name="preference_group_app">App</string>
|
||||||
<string name="bitmessage_service_description">Hält die Verbindung zum Bitmessage-Netzwerk.</string>
|
<string name="bitmessage_service_description">Hält die Verbindung zum Bitmessage-Netzwerk.</string>
|
||||||
<string name="preference_port">Port</string>
|
<string name="preference_port">Port</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -37,10 +37,6 @@
|
|||||||
<string name="archive">Archive</string>
|
<string name="archive">Archive</string>
|
||||||
<string name="empty_trash">Empty Trash</string>
|
<string name="empty_trash">Empty Trash</string>
|
||||||
<string name="stream_number">Stream #%d</string>
|
<string name="stream_number">Stream #%d</string>
|
||||||
<string name="trusted_node">Trusted node</string>
|
|
||||||
<string name="trusted_node_summary">Use this node for synchronization</string>
|
|
||||||
<string name="sync_timeout">Synchronization Timeout</string>
|
|
||||||
<string name="sync_timeout_summary">Timeout in seconds</string>
|
|
||||||
<string name="write_message">Write message</string>
|
<string name="write_message">Write message</string>
|
||||||
<string name="full_node">Full node</string>
|
<string name="full_node">Full node</string>
|
||||||
<string name="send">Send</string>
|
<string name="send">Send</string>
|
||||||
@ -49,12 +45,9 @@
|
|||||||
<string name="proof_of_work_title">Proof of Work</string>
|
<string name="proof_of_work_title">Proof of Work</string>
|
||||||
<string name="proof_of_work_text_0">Doing work to send message</string>
|
<string name="proof_of_work_text_0">Doing work to send message</string>
|
||||||
<string name="proof_of_work_text_n" tools:ignore="PluralsCandidate">Doing work to send message (%1$d queued)</string>
|
<string name="proof_of_work_text_n" tools:ignore="PluralsCandidate">Doing work to send message (%1$d queued)</string>
|
||||||
<string name="error_invalid_sync_port">Invalid port in synchronization settings: %s</string>
|
|
||||||
<string name="compose_body_hint">Write message</string>
|
<string name="compose_body_hint">Write message</string>
|
||||||
<string name="contacts_and_subscriptions">Contacts</string>
|
<string name="contacts_and_subscriptions">Contacts</string>
|
||||||
<string name="subscribed">Subscribed</string>
|
<string name="subscribed">Subscribed</string>
|
||||||
<string name="server_pow">Server POW</string>
|
|
||||||
<string name="server_pow_summary">Trusted node does proof of work</string>
|
|
||||||
<string name="full_node_warning">Running a full Bitmessage node uses a lot of traffic, which could be expensive on a mobile network. Are you sure you want to start a full node?</string>
|
<string name="full_node_warning">Running a full Bitmessage node uses a lot of traffic, which could be expensive on a mobile network. Are you sure you want to start a full node?</string>
|
||||||
<string name="about">About Abit</string>
|
<string name="about">About Abit</string>
|
||||||
<string name="about_summary">Open source dependencies.</string>
|
<string name="about_summary">Open source dependencies.</string>
|
||||||
@ -142,13 +135,10 @@ As an alternative you could configure a trusted node in the settings, but as of
|
|||||||
<string name="emulate_conversations_initialize">Group existing messages by subject</string>
|
<string name="emulate_conversations_initialize">Group existing messages by subject</string>
|
||||||
<string name="emulate_conversations_batch">Grouping existing messages by subject</string>
|
<string name="emulate_conversations_batch">Grouping existing messages by subject</string>
|
||||||
<string name="preference_group_user_experience">Behaviour</string>
|
<string name="preference_group_user_experience">Behaviour</string>
|
||||||
<string name="preference_group_user_experience_summary">Change how messages are displayed</string>
|
|
||||||
<string name="preference_group_network_and_performance">Network & Performance</string>
|
<string name="preference_group_network_and_performance">Network & Performance</string>
|
||||||
<string name="preference_group_network_and_performance_summary">Tweak network usage and protocol details</string>
|
|
||||||
<string name="preference_group_advanced">Advanced</string>
|
<string name="preference_group_advanced">Advanced</string>
|
||||||
<string name="preference_group_advanced_summary"></string>
|
|
||||||
<string name="preference_group_experimental">Experimental</string>
|
<string name="preference_group_experimental">Experimental</string>
|
||||||
<string name="preference_group_experimental_summary">Only change if you know what you\'re doing</string>
|
<string name="preference_group_app">App</string>
|
||||||
<string name="require_charging">Require charging</string>
|
<string name="require_charging">Require charging</string>
|
||||||
<string name="require_charging_summary">Only connect when device is plugged in</string>
|
<string name="require_charging_summary">Only connect when device is plugged in</string>
|
||||||
<string name="unknown">Unknown</string>
|
<string name="unknown">Unknown</string>
|
||||||
|
@ -1,92 +1,94 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceCategory android:title="@string/preference_group_user_experience">
|
||||||
android:key="preference_ux"
|
|
||||||
android:persistent="false"
|
|
||||||
android:summary="@string/preference_group_user_experience_summary"
|
|
||||||
android:title="@string/preference_group_user_experience">
|
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
|
android:icon="@drawable/ic_separate_identities"
|
||||||
android:key="separate_identities"
|
android:key="separate_identities"
|
||||||
android:summary="@string/preference_separate_identities_summary"
|
android:summary="@string/preference_separate_identities_summary"
|
||||||
android:title="@string/preference_separate_identities" />
|
android:title="@string/preference_separate_identities" />
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
|
android:icon="@drawable/ic_emulate_conversations"
|
||||||
android:key="emulate_conversations"
|
android:key="emulate_conversations"
|
||||||
android:summary="@string/emulate_conversations_summary"
|
android:summary="@string/emulate_conversations_summary"
|
||||||
android:title="@string/emulate_conversations" />
|
android:title="@string/emulate_conversations" />
|
||||||
<Preference
|
<Preference
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
|
android:icon="@drawable/ic_emulate_conversations"
|
||||||
android:key="emulate_conversations_initialize"
|
android:key="emulate_conversations_initialize"
|
||||||
android:summary="@string/emulate_conversations_summary"
|
android:summary="@string/emulate_conversations_summary"
|
||||||
android:title="@string/emulate_conversations_initialize" />
|
android:title="@string/emulate_conversations_initialize" />
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceCategory android:title="@string/preference_group_network_and_performance">
|
||||||
android:key="preference_network_and_performance"
|
|
||||||
android:persistent="false"
|
|
||||||
android:summary="@string/preference_group_network_and_performance_summary"
|
|
||||||
android:title="@string/preference_group_network_and_performance">
|
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
|
android:icon="@drawable/ic_network_wifi"
|
||||||
android:key="wifi_only"
|
android:key="wifi_only"
|
||||||
android:summary="@string/wifi_only_summary"
|
android:summary="@string/wifi_only_summary"
|
||||||
android:title="@string/wifi_only" />
|
android:title="@string/wifi_only" />
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
|
android:icon="@drawable/ic_battery_charging"
|
||||||
android:key="require_charging"
|
android:key="require_charging"
|
||||||
android:summary="@string/require_charging_summary"
|
android:summary="@string/require_charging_summary"
|
||||||
android:title="@string/require_charging" />
|
android:title="@string/require_charging" />
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
|
android:icon="@drawable/ic_check_all"
|
||||||
android:key="request_acknowledgements"
|
android:key="request_acknowledgements"
|
||||||
android:summary="@string/request_acknowledgements_summary"
|
android:summary="@string/request_acknowledgements_summary"
|
||||||
android:title="@string/request_acknowledgements" />
|
android:title="@string/request_acknowledgements" />
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceCategory android:title="@string/preference_group_advanced">
|
||||||
android:key="preference_advanced"
|
|
||||||
android:persistent="false"
|
|
||||||
android:summary="@string/preference_group_advanced_summary"
|
|
||||||
android:title="@string/preference_group_advanced">
|
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
|
android:icon="@drawable/ic_broom"
|
||||||
android:key="cleanup"
|
android:key="cleanup"
|
||||||
android:summary="@string/cleanup_summary"
|
android:summary="@string/cleanup_summary"
|
||||||
android:title="@string/cleanup" />
|
android:title="@string/cleanup" />
|
||||||
<Preference
|
<Preference
|
||||||
|
android:icon="@drawable/ic_export"
|
||||||
android:key="export"
|
android:key="export"
|
||||||
android:summary="@string/export_data_summary"
|
android:summary="@string/export_data_summary"
|
||||||
android:title="@string/export_data" />
|
android:title="@string/export_data" />
|
||||||
<Preference
|
<Preference
|
||||||
|
android:icon="@drawable/ic_import"
|
||||||
android:key="import"
|
android:key="import"
|
||||||
android:summary="@string/import_data_summary"
|
android:summary="@string/import_data_summary"
|
||||||
android:title="@string/import_data" />
|
android:title="@string/import_data" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
|
android:icon="@drawable/ic_bug_report"
|
||||||
android:key="status"
|
android:key="status"
|
||||||
android:summary="@string/status_summary"
|
android:summary="@string/status_summary"
|
||||||
android:title="@string/status" />
|
android:title="@string/status" />
|
||||||
|
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:defaultValue="8444"
|
android:defaultValue="8444"
|
||||||
|
android:icon="@drawable/ic_port"
|
||||||
android:key="listening_port"
|
android:key="listening_port"
|
||||||
|
android:numeric="integer"
|
||||||
android:summary="@string/preference_port_summary"
|
android:summary="@string/preference_port_summary"
|
||||||
android:title="@string/preference_port"
|
android:title="@string/preference_port" />
|
||||||
android:numeric="integer"/>
|
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="@string/preference_group_app">
|
||||||
<Preference
|
<Preference
|
||||||
|
android:icon="@drawable/ic_info"
|
||||||
android:key="about"
|
android:key="about"
|
||||||
android:summary="@string/about_summary"
|
android:summary="@string/about_summary"
|
||||||
android:title="@string/about" />
|
android:title="@string/about" />
|
||||||
<Preference
|
<Preference
|
||||||
|
android:icon="@drawable/ic_support_app"
|
||||||
android:key="help_out"
|
android:key="help_out"
|
||||||
android:summary="@string/help_out_summary"
|
android:summary="@string/help_out_summary"
|
||||||
android:title="@string/help_out">
|
android:title="@string/help_out">
|
||||||
@ -94,4 +96,5 @@
|
|||||||
android:action="android.intent.action.VIEW"
|
android:action="android.intent.action.VIEW"
|
||||||
android:data="@string/help_out_link" />
|
android:data="@string/help_out_link" />
|
||||||
</Preference>
|
</Preference>
|
||||||
|
</PreferenceCategory>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@ -21,6 +21,7 @@ import ch.dissem.apps.abit.repository.AndroidAddressRepository
|
|||||||
import ch.dissem.apps.abit.repository.AndroidLabelRepository
|
import ch.dissem.apps.abit.repository.AndroidLabelRepository
|
||||||
import ch.dissem.apps.abit.repository.AndroidMessageRepository
|
import ch.dissem.apps.abit.repository.AndroidMessageRepository
|
||||||
import ch.dissem.apps.abit.repository.SqlHelper
|
import ch.dissem.apps.abit.repository.SqlHelper
|
||||||
|
import ch.dissem.apps.abit.util.preferences
|
||||||
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography
|
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||||
import ch.dissem.bitmessage.entity.ObjectMessage
|
import ch.dissem.bitmessage.entity.ObjectMessage
|
||||||
@ -67,7 +68,7 @@ class AndroidMessageRepositoryTest : TestBase() {
|
|||||||
|
|
||||||
val addressRepo = AndroidAddressRepository(sqlHelper)
|
val addressRepo = AndroidAddressRepository(sqlHelper)
|
||||||
val labelRepo = AndroidLabelRepository(sqlHelper, RuntimeEnvironment.application)
|
val labelRepo = AndroidLabelRepository(sqlHelper, RuntimeEnvironment.application)
|
||||||
repo = AndroidMessageRepository(sqlHelper)
|
repo = AndroidMessageRepository(sqlHelper, RuntimeEnvironment.application.preferences)
|
||||||
mockedInternalContext(
|
mockedInternalContext(
|
||||||
cryptography = BouncyCryptography(),
|
cryptography = BouncyCryptography(),
|
||||||
addressRepository = addressRepo,
|
addressRepository = addressRepo,
|
||||||
|
@ -18,6 +18,7 @@ package ch.dissem.bitmessage.repository
|
|||||||
|
|
||||||
import android.os.Build.VERSION_CODES.LOLLIPOP
|
import android.os.Build.VERSION_CODES.LOLLIPOP
|
||||||
import ch.dissem.apps.abit.repository.*
|
import ch.dissem.apps.abit.repository.*
|
||||||
|
import ch.dissem.apps.abit.util.preferences
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||||
import ch.dissem.bitmessage.entity.ObjectMessage
|
import ch.dissem.bitmessage.entity.ObjectMessage
|
||||||
import ch.dissem.bitmessage.entity.Plaintext
|
import ch.dissem.bitmessage.entity.Plaintext
|
||||||
@ -60,7 +61,7 @@ class AndroidProofOfWorkRepositoryTest : TestBase() {
|
|||||||
RuntimeEnvironment.application.deleteDatabase(SqlHelper.DATABASE_NAME)
|
RuntimeEnvironment.application.deleteDatabase(SqlHelper.DATABASE_NAME)
|
||||||
val sqlHelper = SqlHelper(RuntimeEnvironment.application)
|
val sqlHelper = SqlHelper(RuntimeEnvironment.application)
|
||||||
addressRepo = AndroidAddressRepository(sqlHelper)
|
addressRepo = AndroidAddressRepository(sqlHelper)
|
||||||
messageRepo = AndroidMessageRepository(sqlHelper)
|
messageRepo = AndroidMessageRepository(sqlHelper, RuntimeEnvironment.application.preferences)
|
||||||
repo = AndroidProofOfWorkRepository(sqlHelper)
|
repo = AndroidProofOfWorkRepository(sqlHelper)
|
||||||
mockedInternalContext(
|
mockedInternalContext(
|
||||||
addressRepository = addressRepo,
|
addressRepository = addressRepo,
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.2.51'
|
ext.kotlin_version = '1.2.71'
|
||||||
ext.anko_version = '0.10.5'
|
ext.anko_version = '0.10.5'
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
|
||||||
google()
|
google()
|
||||||
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.1.3'
|
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath 'com.github.ben-manes:gradle-versions-plugin:0.20.0'
|
classpath 'com.github.ben-manes:gradle-versions-plugin:0.20.0'
|
||||||
|
|
||||||
@ -21,7 +21,6 @@ allprojects {
|
|||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
mavenCentral()
|
|
||||||
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
|
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
|
||||||
maven { url "https://jitpack.io" }
|
maven { url "https://jitpack.io" }
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||||
|
android.enableJetifier=true
|
||||||
|
android.useAndroidX=true
|
||||||
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||||
|
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
#Sat Mar 03 14:35:52 CET 2018
|
#Tue Aug 28 16:14:32 CEST 2018
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||||
|
Loading…
Reference in New Issue
Block a user