Improve utilities
This commit is contained in:
parent
46e5bb7ece
commit
49e77199b0
@ -26,6 +26,7 @@ import android.view.*
|
||||
import android.widget.Toast
|
||||
import ch.dissem.apps.abit.service.Singleton
|
||||
import ch.dissem.apps.abit.util.Drawables
|
||||
import ch.dissem.apps.abit.util.qrCode
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||
import ch.dissem.bitmessage.wif.WifExporter
|
||||
import com.mikepenz.community_material_typeface_library.CommunityMaterial
|
||||
@ -185,7 +186,7 @@ class AddressDetailFragment : Fragment() {
|
||||
}
|
||||
|
||||
// QR code
|
||||
qr_code.setImageBitmap(Drawables.qrCode(item))
|
||||
qr_code.setImageBitmap(item.qrCode())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@ import android.widget.ArrayAdapter
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import ch.dissem.apps.abit.service.Singleton
|
||||
import ch.dissem.apps.abit.util.FabUtils
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||
import com.google.zxing.integration.android.IntentIntegrator
|
||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
||||
@ -107,7 +106,7 @@ class AddressListFragment : AbstractItemListFragment<Void, BitmessageAddress>()
|
||||
val menu = FabSpeedDialMenu(activity)
|
||||
menu.add(R.string.scan_qr_code).setIcon(R.drawable.ic_action_qr_code)
|
||||
menu.add(R.string.create_contact).setIcon(R.drawable.ic_action_create_contact)
|
||||
FabUtils.initFab(activity, R.drawable.ic_action_add_contact, menu)
|
||||
activity.initFab(R.drawable.ic_action_add_contact, menu)
|
||||
.addOnMenuItemClickListener { _, _, itemId ->
|
||||
when (itemId) {
|
||||
1 -> IntentIntegrator.forSupportFragment(this@AddressListFragment)
|
||||
|
@ -19,7 +19,6 @@ package ch.dissem.apps.abit
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.annotation.IdRes
|
||||
import android.support.v4.app.Fragment
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
@ -28,9 +27,9 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import ch.dissem.apps.abit.adapter.ConversationAdapter
|
||||
import ch.dissem.apps.abit.service.Singleton
|
||||
import ch.dissem.apps.abit.util.Assets
|
||||
import ch.dissem.apps.abit.util.Drawables
|
||||
import ch.dissem.apps.abit.util.Strings.prepareMessageExtract
|
||||
import ch.dissem.apps.abit.util.getDrawable
|
||||
import ch.dissem.bitmessage.entity.Conversation
|
||||
import ch.dissem.bitmessage.entity.Plaintext
|
||||
import com.mikepenz.google_material_typeface_library.GoogleMaterial
|
||||
@ -148,7 +147,7 @@ class ConversationDetailFragment : Fragment() {
|
||||
val message = messages[position]
|
||||
|
||||
viewHolder.avatar.setImageDrawable(Identicon(message.from))
|
||||
viewHolder.status.setImageResource(Assets.getStatusDrawable(message.status))
|
||||
viewHolder.status.setImageResource(message.status.getDrawable())
|
||||
viewHolder.sender.text = message.from.toString()
|
||||
viewHolder.extract.text = prepareMessageExtract(message.text)
|
||||
viewHolder.item = message
|
||||
|
@ -33,7 +33,6 @@ import ch.dissem.apps.abit.listener.ListSelectionListener
|
||||
import ch.dissem.apps.abit.repository.AndroidMessageRepository
|
||||
import ch.dissem.apps.abit.service.Singleton
|
||||
import ch.dissem.apps.abit.service.Singleton.currentLabel
|
||||
import ch.dissem.apps.abit.util.FabUtils
|
||||
import ch.dissem.bitmessage.entity.Conversation
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||
import ch.dissem.bitmessage.utils.ConversationService
|
||||
@ -248,7 +247,7 @@ class ConversationListFragment : Fragment(), ListHolder<Label> {
|
||||
val menu = FabSpeedDialMenu(context)
|
||||
menu.add(R.string.broadcast).setIcon(R.drawable.ic_action_broadcast)
|
||||
menu.add(R.string.personal_message).setIcon(R.drawable.ic_action_personal)
|
||||
FabUtils.initFab(context, R.drawable.ic_action_compose_message, menu)
|
||||
context.initFab(R.drawable.ic_action_compose_message, menu)
|
||||
.addOnMenuItemClickListener { _, _, itemId ->
|
||||
val identity = Singleton.getIdentity(context)
|
||||
if (identity == null) {
|
||||
|
@ -19,6 +19,7 @@ package ch.dissem.apps.abit
|
||||
import android.content.Intent
|
||||
import android.graphics.Point
|
||||
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
|
||||
@ -54,6 +55,7 @@ import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IProfile
|
||||
import com.mikepenz.materialdrawer.model.interfaces.Nameable
|
||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDial
|
||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import org.jetbrains.anko.doAsync
|
||||
import org.jetbrains.anko.uiThread
|
||||
@ -538,6 +540,25 @@ class MainActivity : AppCompatActivity(), ListSelectionListener<Serializable> {
|
||||
supportActionBar?.title = title
|
||||
}
|
||||
|
||||
fun initFab(@DrawableRes drawableRes: Int, menu: FabSpeedDialMenu): FabSpeedDial {
|
||||
val fab = floatingActionButton ?: throw IllegalStateException("Fab must not be null")
|
||||
fab.removeAllOnMenuItemClickListeners()
|
||||
fab.show()
|
||||
fab.closeMenu()
|
||||
val mainFab = fab.mainFab
|
||||
mainFab.setImageResource(drawableRes)
|
||||
fab.setMenu(menu)
|
||||
fab.addOnStateChangeListener { isOpened: Boolean ->
|
||||
if (isOpened) {
|
||||
// It will be turned 45 degrees, which makes an x out of the +
|
||||
mainFab.setImageResource(R.drawable.ic_action_add)
|
||||
} else {
|
||||
mainFab.setImageResource(drawableRes)
|
||||
}
|
||||
}
|
||||
return fab
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EXTRA_SHOW_MESSAGE = "ch.dissem.abit.ShowMessage"
|
||||
const val EXTRA_SHOW_LABEL = "ch.dissem.abit.ShowLabel"
|
||||
|
@ -31,16 +31,15 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import ch.dissem.apps.abit.adapter.LabelAdapter
|
||||
import ch.dissem.apps.abit.service.Singleton
|
||||
import ch.dissem.apps.abit.util.Assets
|
||||
import ch.dissem.apps.abit.util.Constants.BITMESSAGE_ADDRESS_PATTERN
|
||||
import ch.dissem.apps.abit.util.Constants.BITMESSAGE_URL_SCHEMA
|
||||
import ch.dissem.apps.abit.util.Drawables
|
||||
import ch.dissem.apps.abit.util.Labels
|
||||
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.mikepenz.google_material_typeface_library.GoogleMaterial
|
||||
import com.mikepenz.iconics.view.IconicsImageView
|
||||
import kotlinx.android.synthetic.main.fragment_message_detail.*
|
||||
import java.util.*
|
||||
|
||||
@ -86,8 +85,8 @@ class MessageDetailFragment : Fragment() {
|
||||
// Show the dummy content as text in a TextView.
|
||||
item?.let { item ->
|
||||
subject.text = item.subject
|
||||
status.setImageResource(Assets.getStatusDrawable(item.status))
|
||||
status.contentDescription = getString(Assets.getStatusString(item.status))
|
||||
status.setImageResource(item.status.getDrawable())
|
||||
status.contentDescription = getString(item.status.getString())
|
||||
avatar.setImageDrawable(Identicon(item.from))
|
||||
val senderClickListener: (View) -> Unit = {
|
||||
MainActivity.apply {
|
||||
@ -230,7 +229,7 @@ class MessageDetailFragment : Fragment() {
|
||||
val message = messages[position]
|
||||
|
||||
viewHolder.avatar.setImageDrawable(Identicon(message.from))
|
||||
viewHolder.status.setImageResource(Assets.getStatusDrawable(message.status))
|
||||
viewHolder.status.setImageResource(message.status.getDrawable())
|
||||
viewHolder.sender.text = message.from.toString()
|
||||
viewHolder.extract.text = prepareMessageExtract(message.text)
|
||||
viewHolder.item = message
|
||||
|
@ -33,7 +33,6 @@ import ch.dissem.apps.abit.listener.ListSelectionListener
|
||||
import ch.dissem.apps.abit.repository.AndroidMessageRepository
|
||||
import ch.dissem.apps.abit.service.Singleton
|
||||
import ch.dissem.apps.abit.service.Singleton.currentLabel
|
||||
import ch.dissem.apps.abit.util.FabUtils
|
||||
import ch.dissem.bitmessage.entity.Plaintext
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||
import com.h6ah4i.android.widget.advrecyclerview.animator.SwipeDismissItemAnimator
|
||||
@ -98,7 +97,11 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
||||
isLoading = true
|
||||
swipeableMessageAdapter?.let { messageAdapter ->
|
||||
doAsync {
|
||||
val messages = messageRepo.findMessages(currentLabel.value, messageAdapter.itemCount, PAGE_SIZE)
|
||||
val messages = messageRepo.findMessages(
|
||||
currentLabel.value,
|
||||
messageAdapter.itemCount,
|
||||
PAGE_SIZE
|
||||
)
|
||||
onUiThread {
|
||||
messageAdapter.addAll(messages)
|
||||
isLoading = false
|
||||
@ -149,7 +152,11 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
||||
loadMoreItems()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View =
|
||||
inflater.inflate(R.layout.fragment_message_list, container, false)
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
@ -213,8 +220,11 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
||||
recycler_view.itemAnimator = animator
|
||||
recycler_view.addOnScrollListener(recyclerViewOnScrollListener)
|
||||
|
||||
recycler_view.addItemDecoration(SimpleListDividerDecorator(
|
||||
ContextCompat.getDrawable(context, R.drawable.list_divider_h), true))
|
||||
recycler_view.addItemDecoration(
|
||||
SimpleListDividerDecorator(
|
||||
ContextCompat.getDrawable(context, R.drawable.list_divider_h), true
|
||||
)
|
||||
)
|
||||
|
||||
// NOTE:
|
||||
// The initialization order is very important! This order determines the priority of
|
||||
@ -235,12 +245,14 @@ class MessageListFragment : Fragment(), ListHolder<Label> {
|
||||
val menu = FabSpeedDialMenu(context)
|
||||
menu.add(R.string.broadcast).setIcon(R.drawable.ic_action_broadcast)
|
||||
menu.add(R.string.personal_message).setIcon(R.drawable.ic_action_personal)
|
||||
FabUtils.initFab(context, R.drawable.ic_action_compose_message, menu)
|
||||
context.initFab(R.drawable.ic_action_compose_message, menu)
|
||||
.addOnMenuItemClickListener { _, _, itemId ->
|
||||
val identity = Singleton.getIdentity(context)
|
||||
if (identity == null) {
|
||||
Toast.makeText(activity, R.string.no_identity_warning,
|
||||
Toast.LENGTH_LONG).show()
|
||||
Toast.makeText(
|
||||
activity, R.string.no_identity_warning,
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
} else {
|
||||
when (itemId) {
|
||||
1 -> {
|
||||
|
@ -13,8 +13,8 @@ import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import ch.dissem.apps.abit.*
|
||||
import ch.dissem.apps.abit.service.Singleton
|
||||
import ch.dissem.apps.abit.util.Assets
|
||||
import ch.dissem.apps.abit.util.Constants
|
||||
import ch.dissem.apps.abit.util.getDrawable
|
||||
import ch.dissem.bitmessage.entity.Conversation
|
||||
import ch.dissem.bitmessage.entity.Plaintext
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||
@ -61,7 +61,7 @@ class ConversationAdapter internal constructor(
|
||||
sender.setOnClickListener(senderClickListener)
|
||||
|
||||
recipient.text = message.to.toString()
|
||||
status.setImageResource(Assets.getStatusDrawable(message.status))
|
||||
status.setImageResource(message.status.getDrawable())
|
||||
text.text = message.text
|
||||
|
||||
Linkify.addLinks(text, Linkify.WEB_URLS)
|
||||
|
@ -29,8 +29,9 @@ 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.Assets
|
||||
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
|
||||
@ -48,7 +49,8 @@ import java.util.*
|
||||
* @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 {
|
||||
class SwipeableMessageAdapter : RecyclerView.Adapter<SwipeableMessageAdapter.ViewHolder>(),
|
||||
SwipeableItemAdapter<SwipeableMessageAdapter.ViewHolder>, SwipeableItemConstants {
|
||||
|
||||
private val data = LinkedList<Plaintext>()
|
||||
var eventListener: EventListener? = null
|
||||
@ -84,7 +86,8 @@ class SwipeableMessageAdapter : RecyclerView.Adapter<SwipeableMessageAdapter.Vie
|
||||
|
||||
init {
|
||||
itemViewOnClickListener = View.OnClickListener { view -> onItemViewClick(view) }
|
||||
swipeableViewContainerOnClickListener = View.OnClickListener { view -> onSwipeableViewContainerClick(view) }
|
||||
swipeableViewContainerOnClickListener =
|
||||
View.OnClickListener { view -> onSwipeableViewContainerClick(view) }
|
||||
|
||||
// SwipeableItemAdapter requires stable ID, and also
|
||||
// have to implement the getItemId() method appropriately.
|
||||
@ -134,7 +137,8 @@ class SwipeableMessageAdapter : RecyclerView.Adapter<SwipeableMessageAdapter.Vie
|
||||
|
||||
private fun onSwipeableViewContainerClick(v: View) {
|
||||
eventListener?.onItemViewClicked(
|
||||
RecyclerViewAdapterUtils.getParentViewHolderItemView(v))
|
||||
RecyclerViewAdapterUtils.getParentViewHolderItemView(v)
|
||||
)
|
||||
}
|
||||
|
||||
fun getItem(position: Int) = data[position]
|
||||
@ -168,8 +172,8 @@ class SwipeableMessageAdapter : RecyclerView.Adapter<SwipeableMessageAdapter.Vie
|
||||
|
||||
// set data
|
||||
avatar.setImageDrawable(Identicon(item.from))
|
||||
status.setImageResource(Assets.getStatusDrawable(item.status))
|
||||
status.contentDescription = holder.status.context.getString(Assets.getStatusString(item.status))
|
||||
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)
|
||||
@ -194,16 +198,18 @@ class SwipeableMessageAdapter : RecyclerView.Adapter<SwipeableMessageAdapter.Vie
|
||||
|
||||
@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
|
||||
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
|
||||
}
|
||||
else -> R.drawable.bg_swipe_item_neutral
|
||||
})
|
||||
)
|
||||
|
||||
@SuppressLint("SwitchIntDef")
|
||||
override fun onSwipeItem(holder: ViewHolder, position: Int, result: Int) =
|
||||
@ -222,7 +228,10 @@ class SwipeableMessageAdapter : RecyclerView.Adapter<SwipeableMessageAdapter.Vie
|
||||
notifyItemChanged(selectedPosition)
|
||||
}
|
||||
|
||||
private class SwipeLeftResultAction internal constructor(adapter: SwipeableMessageAdapter, position: Int) : SwipeResultActionMoveToSwipedDirection() {
|
||||
private class SwipeLeftResultAction internal constructor(
|
||||
adapter: SwipeableMessageAdapter,
|
||||
position: Int
|
||||
) : SwipeResultActionMoveToSwipedDirection() {
|
||||
private var adapter: SwipeableMessageAdapter? = adapter
|
||||
private val item = adapter.data[position]
|
||||
|
||||
@ -235,7 +244,10 @@ class SwipeableMessageAdapter : RecyclerView.Adapter<SwipeableMessageAdapter.Vie
|
||||
}
|
||||
}
|
||||
|
||||
private class SwipeRightResultAction internal constructor(adapter: SwipeableMessageAdapter, position: Int) : SwipeResultActionRemoveItem() {
|
||||
private class SwipeRightResultAction internal constructor(
|
||||
adapter: SwipeableMessageAdapter,
|
||||
position: Int
|
||||
) : SwipeResultActionRemoveItem() {
|
||||
private var adapter: SwipeableMessageAdapter? = adapter
|
||||
private val item = adapter.data[position]
|
||||
|
||||
|
@ -10,7 +10,7 @@ import android.view.WindowManager
|
||||
import android.widget.ImageView
|
||||
import android.widget.RelativeLayout
|
||||
import ch.dissem.apps.abit.service.Singleton
|
||||
import ch.dissem.apps.abit.util.Drawables
|
||||
import ch.dissem.apps.abit.util.qrCode
|
||||
import com.mikepenz.materialdrawer.AccountHeader
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IProfile
|
||||
|
||||
@ -23,7 +23,7 @@ class ProfileImageListener(private val ctx: Context) : AccountHeader.OnAccountHe
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
|
||||
val imageView = ImageView(ctx)
|
||||
imageView.setImageBitmap(Drawables.qrCode(Singleton.getIdentity(ctx)))
|
||||
imageView.setImageBitmap(Singleton.getIdentity(ctx)?.qrCode())
|
||||
imageView.setOnClickListener { dialog.dismiss() }
|
||||
dialog.addContentView(
|
||||
imageView,
|
||||
|
@ -17,6 +17,7 @@
|
||||
package ch.dissem.apps.abit.notification
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
@ -27,18 +28,15 @@ import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.Spanned
|
||||
import android.text.style.StyleSpan
|
||||
|
||||
import ch.dissem.apps.abit.Identicon
|
||||
import ch.dissem.apps.abit.MainActivity
|
||||
import ch.dissem.apps.abit.R
|
||||
import ch.dissem.apps.abit.service.BitmessageIntentService
|
||||
import ch.dissem.bitmessage.entity.Plaintext
|
||||
|
||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||
import ch.dissem.apps.abit.MainActivity.Companion.EXTRA_REPLY_TO_MESSAGE
|
||||
import ch.dissem.apps.abit.MainActivity.Companion.EXTRA_SHOW_MESSAGE
|
||||
import ch.dissem.apps.abit.R
|
||||
import ch.dissem.apps.abit.service.BitmessageIntentService
|
||||
import ch.dissem.apps.abit.service.BitmessageIntentService.Companion.EXTRA_DELETE_MESSAGE
|
||||
import ch.dissem.apps.abit.util.Drawables.toBitmap
|
||||
import ch.dissem.apps.abit.util.toBitmap
|
||||
import ch.dissem.bitmessage.entity.Plaintext
|
||||
|
||||
class NewMessageNotification(ctx: Context) : AbstractNotification(ctx) {
|
||||
|
||||
@ -53,7 +51,7 @@ class NewMessageNotification(ctx: Context) : AbstractNotification(ctx) {
|
||||
bigText.setSpan(SPAN_EMPHASIS, 0, subject.length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
builder.setSmallIcon(R.drawable.ic_notification_new_message)
|
||||
.setLargeIcon(toBitmap(Identicon(plaintext.from), 192))
|
||||
.setLargeIcon(Identicon(plaintext.from).toBitmap(192))
|
||||
.setContentTitle(plaintext.from.toString())
|
||||
.setContentText(plaintext.subject)
|
||||
.setStyle(BigTextStyle().bigText(bigText))
|
||||
|
@ -20,7 +20,7 @@ import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.database.DatabaseUtils
|
||||
import ch.dissem.apps.abit.util.Labels
|
||||
import ch.dissem.apps.abit.util.getText
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||
import ch.dissem.bitmessage.ports.AbstractLabelRepository
|
||||
import ch.dissem.bitmessage.ports.MessageRepository
|
||||
@ -30,7 +30,8 @@ import java.util.*
|
||||
/**
|
||||
* [MessageRepository] implementation using the Android SQL API.
|
||||
*/
|
||||
class AndroidLabelRepository(private val sql: SqlHelper, private val context: Context) : AbstractLabelRepository() {
|
||||
class AndroidLabelRepository(private val sql: SqlHelper, private val context: Context) :
|
||||
AbstractLabelRepository() {
|
||||
|
||||
override fun find(where: String): List<Label> {
|
||||
val result = LinkedList<Label>()
|
||||
@ -62,7 +63,12 @@ class AndroidLabelRepository(private val sql: SqlHelper, private val context: Co
|
||||
db.update(TABLE_NAME, values, "id=?", arrayOf(label.id.toString()))
|
||||
} else {
|
||||
db.transaction {
|
||||
val exists = DatabaseUtils.queryNumEntries(db, TABLE_NAME, "label=?", arrayOf(label.toString())) > 0
|
||||
val exists = DatabaseUtils.queryNumEntries(
|
||||
db,
|
||||
TABLE_NAME,
|
||||
"label=?",
|
||||
arrayOf(label.toString())
|
||||
) > 0
|
||||
|
||||
if (exists) {
|
||||
val values = ContentValues()
|
||||
@ -82,7 +88,8 @@ class AndroidLabelRepository(private val sql: SqlHelper, private val context: Co
|
||||
}
|
||||
}
|
||||
|
||||
internal fun findLabels(msgId: Any) = find("id IN (SELECT label_id FROM Message_Label WHERE message_id=$msgId)")
|
||||
internal fun findLabels(msgId: Any) =
|
||||
find("id IN (SELECT label_id FROM Message_Label WHERE message_id=$msgId)")
|
||||
|
||||
companion object {
|
||||
val LABEL_ARCHIVE = Label("archive", null, 0).apply { id = Long.MAX_VALUE }
|
||||
@ -97,11 +104,12 @@ class AndroidLabelRepository(private val sql: SqlHelper, private val context: Co
|
||||
internal fun getLabel(c: Cursor, context: Context): Label {
|
||||
val typeName = c.getString(c.getColumnIndex(COLUMN_TYPE))
|
||||
val type = if (typeName == null) null else Label.Type.valueOf(typeName)
|
||||
val text: String? = Labels.getText(type, null, context)
|
||||
val text: String? = type?.getText(null, context)
|
||||
val label = Label(
|
||||
text ?: c.getString(c.getColumnIndex(COLUMN_LABEL)),
|
||||
type,
|
||||
c.getInt(c.getColumnIndex(COLUMN_COLOR)))
|
||||
c.getInt(c.getColumnIndex(COLUMN_COLOR))
|
||||
)
|
||||
label.id = c.getLong(c.getColumnIndex(COLUMN_ID))
|
||||
return label
|
||||
}
|
||||
|
@ -43,28 +43,25 @@ object Assets {
|
||||
} catch (e: IOException) {
|
||||
throw RuntimeException(e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@DrawableRes
|
||||
fun getStatusDrawable(status: Plaintext.Status) = when (status) {
|
||||
Plaintext.Status.RECEIVED -> 0
|
||||
Plaintext.Status.DRAFT -> R.drawable.draft
|
||||
Plaintext.Status.PUBKEY_REQUESTED -> R.drawable.public_key
|
||||
Plaintext.Status.DOING_PROOF_OF_WORK -> R.drawable.ic_notification_proof_of_work
|
||||
Plaintext.Status.SENT -> R.drawable.sent
|
||||
Plaintext.Status.SENT_ACKNOWLEDGED -> R.drawable.sent_acknowledged
|
||||
else -> 0
|
||||
}
|
||||
|
||||
@StringRes
|
||||
fun getStatusString(status: Plaintext.Status) = when (status) {
|
||||
Plaintext.Status.RECEIVED -> R.string.status_received
|
||||
Plaintext.Status.DRAFT -> R.string.status_draft
|
||||
Plaintext.Status.PUBKEY_REQUESTED -> R.string.status_public_key
|
||||
Plaintext.Status.DOING_PROOF_OF_WORK -> R.string.proof_of_work_title
|
||||
Plaintext.Status.SENT -> R.string.status_sent
|
||||
Plaintext.Status.SENT_ACKNOWLEDGED -> R.string.status_sent_acknowledged
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
fun Plaintext.Status.getDrawable() = when (this) {
|
||||
Plaintext.Status.RECEIVED -> 0
|
||||
Plaintext.Status.DRAFT -> R.drawable.draft
|
||||
Plaintext.Status.PUBKEY_REQUESTED -> R.drawable.public_key
|
||||
Plaintext.Status.DOING_PROOF_OF_WORK -> R.drawable.ic_notification_proof_of_work
|
||||
Plaintext.Status.SENT -> R.drawable.sent
|
||||
Plaintext.Status.SENT_ACKNOWLEDGED -> R.drawable.sent_acknowledged
|
||||
else -> 0
|
||||
}
|
||||
|
||||
fun Plaintext.Status.getString() = when (this) {
|
||||
Plaintext.Status.RECEIVED -> R.string.status_received
|
||||
Plaintext.Status.DRAFT -> R.string.status_draft
|
||||
Plaintext.Status.PUBKEY_REQUESTED -> R.string.status_public_key
|
||||
Plaintext.Status.DOING_PROOF_OF_WORK -> R.string.proof_of_work_title
|
||||
Plaintext.Status.SENT -> R.string.status_sent
|
||||
Plaintext.Status.SENT_ACKNOWLEDGED -> R.string.status_sent_acknowledged
|
||||
else -> 0
|
||||
}
|
||||
|
@ -21,13 +21,14 @@ import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color.BLACK
|
||||
import android.graphics.Color.WHITE
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.Base64
|
||||
import android.util.Base64.NO_WRAP
|
||||
import android.util.Base64.URL_SAFE
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import ch.dissem.apps.abit.Identicon
|
||||
import ch.dissem.apps.abit.R
|
||||
import ch.dissem.apps.abit.util.Drawables.QR_CODE_SIZE
|
||||
import ch.dissem.bitmessage.entity.BitmessageAddress
|
||||
import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.MultiFormatWriter
|
||||
@ -42,61 +43,61 @@ import java.io.ByteArrayOutputStream
|
||||
* Some helper methods to work with drawables.
|
||||
*/
|
||||
object Drawables {
|
||||
private val LOG = LoggerFactory.getLogger(Drawables::class.java)
|
||||
internal val LOG = LoggerFactory.getLogger(Drawables::class.java)
|
||||
|
||||
private const val QR_CODE_SIZE = 350
|
||||
internal const val QR_CODE_SIZE = 350
|
||||
|
||||
fun addIcon(ctx: Context, menu: Menu, menuItem: Int, icon: IIcon): MenuItem {
|
||||
val item = menu.findItem(menuItem)
|
||||
item.icon = IconicsDrawable(ctx, icon).colorRes(R.color.colorPrimaryDarkText).actionBar()
|
||||
return item
|
||||
}
|
||||
|
||||
fun toBitmap(identicon: Identicon, width: Int, height: Int = width): Bitmap {
|
||||
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(bitmap)
|
||||
identicon.setBounds(0, 0, canvas.width, canvas.height)
|
||||
identicon.draw(canvas)
|
||||
return bitmap
|
||||
}
|
||||
|
||||
fun qrCode(address: BitmessageAddress?): Bitmap? {
|
||||
if (address == null) {
|
||||
return null
|
||||
}
|
||||
val link = StringBuilder()
|
||||
link.append(Constants.BITMESSAGE_URL_SCHEMA)
|
||||
link.append(address.address)
|
||||
if (address.alias != null) {
|
||||
link.append("?label=").append(address.alias)
|
||||
}
|
||||
address.pubkey?.apply {
|
||||
link.append(if (address.alias == null) '?' else '&')
|
||||
val pubkey = ByteArrayOutputStream()
|
||||
writer().writeUnencrypted(pubkey)
|
||||
link.append("pubkey=").append(Base64.encodeToString(pubkey.toByteArray(), URL_SAFE or NO_WRAP))
|
||||
|
||||
}
|
||||
val result: BitMatrix
|
||||
try {
|
||||
result = MultiFormatWriter().encode(link.toString(),
|
||||
BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, null)
|
||||
} catch (e: WriterException) {
|
||||
LOG.error(e.message, e)
|
||||
return null
|
||||
}
|
||||
|
||||
val w = result.width
|
||||
val h = result.height
|
||||
val pixels = IntArray(w * h)
|
||||
for (y in 0 until h) {
|
||||
val offset = y * w
|
||||
for (x in 0 until w) {
|
||||
pixels[offset + x] = if (result.get(x, y)) BLACK else WHITE
|
||||
}
|
||||
}
|
||||
val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
|
||||
bitmap.setPixels(pixels, 0, QR_CODE_SIZE, 0, 0, w, h)
|
||||
return bitmap
|
||||
}
|
||||
}
|
||||
|
||||
fun Drawable.toBitmap(width: Int, height: Int = width): Bitmap {
|
||||
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(bitmap)
|
||||
setBounds(0, 0, canvas.width, canvas.height)
|
||||
draw(canvas)
|
||||
return bitmap
|
||||
}
|
||||
|
||||
fun BitmessageAddress.qrCode(): Bitmap? {
|
||||
val link = StringBuilder()
|
||||
link.append(Constants.BITMESSAGE_URL_SCHEMA)
|
||||
link.append(address)
|
||||
if (alias != null) {
|
||||
link.append("?label=").append(alias)
|
||||
}
|
||||
pubkey?.apply {
|
||||
link.append(if (alias == null) '?' else '&')
|
||||
val pubkey = ByteArrayOutputStream()
|
||||
writer().writeUnencrypted(pubkey)
|
||||
link.append("pubkey=")
|
||||
.append(Base64.encodeToString(pubkey.toByteArray(), URL_SAFE or NO_WRAP))
|
||||
|
||||
}
|
||||
val result: BitMatrix
|
||||
try {
|
||||
result = MultiFormatWriter().encode(
|
||||
link.toString(),
|
||||
BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, null
|
||||
)
|
||||
} catch (e: WriterException) {
|
||||
Drawables.LOG.error(e.message, e)
|
||||
return null
|
||||
}
|
||||
|
||||
val w = result.width
|
||||
val h = result.height
|
||||
val pixels = IntArray(w * h)
|
||||
for (y in 0 until h) {
|
||||
val offset = y * w
|
||||
for (x in 0 until w) {
|
||||
pixels[offset + x] = if (result.get(x, y)) BLACK else WHITE
|
||||
}
|
||||
}
|
||||
val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
|
||||
bitmap.setPixels(pixels, 0, QR_CODE_SIZE, 0, 0, w, h)
|
||||
return bitmap
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
package ch.dissem.apps.abit.util
|
||||
|
||||
import android.support.annotation.DrawableRes
|
||||
import ch.dissem.apps.abit.MainActivity
|
||||
import ch.dissem.apps.abit.R
|
||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDial
|
||||
import io.github.kobakei.materialfabspeeddial.FabSpeedDialMenu
|
||||
|
||||
/**
|
||||
* Utilities to work with the common floating action button in the main activity
|
||||
*/
|
||||
object FabUtils {
|
||||
fun initFab(activity: MainActivity, @DrawableRes drawableRes: Int, menu: FabSpeedDialMenu): FabSpeedDial {
|
||||
val fab = activity.floatingActionButton ?: throw IllegalStateException("Fab must not be null")
|
||||
fab.removeAllOnMenuItemClickListeners()
|
||||
fab.show()
|
||||
fab.closeMenu()
|
||||
val mainFab = fab.mainFab
|
||||
mainFab.setImageResource(drawableRes)
|
||||
fab.setMenu(menu)
|
||||
fab.addOnStateChangeListener { isOpened: Boolean ->
|
||||
if (isOpened) {
|
||||
// It will be turned 45 degrees, which makes an x out of the +
|
||||
mainFab.setImageResource(R.drawable.ic_action_add)
|
||||
} else {
|
||||
mainFab.setImageResource(drawableRes)
|
||||
}
|
||||
}
|
||||
return fab
|
||||
}
|
||||
}
|
@ -2,31 +2,27 @@ package ch.dissem.apps.abit.util
|
||||
|
||||
import android.content.Context
|
||||
import android.support.annotation.ColorInt
|
||||
|
||||
import ch.dissem.apps.abit.R
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||
import com.mikepenz.community_material_typeface_library.CommunityMaterial
|
||||
import com.mikepenz.google_material_typeface_library.GoogleMaterial
|
||||
import com.mikepenz.iconics.typeface.IIcon
|
||||
|
||||
import ch.dissem.apps.abit.R
|
||||
import ch.dissem.bitmessage.entity.valueobject.Label
|
||||
|
||||
/*
|
||||
* Helper methods to help with translating the default labels, getting label colors and so on.
|
||||
*/
|
||||
|
||||
fun Label.getText(ctx: Context): String = Labels.getText(type, toString(), ctx)!!
|
||||
fun Label.getText(ctx: Context): String = type?.getText(toString(), ctx) ?: toString()
|
||||
|
||||
object Labels {
|
||||
fun getText(type: Label.Type?, alternative: String?, ctx: Context) = when (type) {
|
||||
Label.Type.INBOX -> ctx.getString(R.string.inbox)
|
||||
Label.Type.DRAFT -> ctx.getString(R.string.draft)
|
||||
Label.Type.OUTBOX -> ctx.getString(R.string.outbox)
|
||||
Label.Type.SENT -> ctx.getString(R.string.sent)
|
||||
Label.Type.UNREAD -> ctx.getString(R.string.unread)
|
||||
Label.Type.TRASH -> ctx.getString(R.string.trash)
|
||||
Label.Type.BROADCAST -> ctx.getString(R.string.broadcasts)
|
||||
else -> alternative
|
||||
}
|
||||
fun Label.Type.getText(alternative: String?, ctx: Context) = when (this) {
|
||||
Label.Type.INBOX -> ctx.getString(R.string.inbox)
|
||||
Label.Type.DRAFT -> ctx.getString(R.string.draft)
|
||||
Label.Type.OUTBOX -> ctx.getString(R.string.outbox)
|
||||
Label.Type.SENT -> ctx.getString(R.string.sent)
|
||||
Label.Type.UNREAD -> ctx.getString(R.string.unread)
|
||||
Label.Type.TRASH -> ctx.getString(R.string.trash)
|
||||
Label.Type.BROADCAST -> ctx.getString(R.string.broadcasts)
|
||||
else -> alternative
|
||||
}
|
||||
|
||||
fun Label.getIcon(): IIcon = when (type) {
|
||||
|
@ -23,7 +23,7 @@ object PowStats {
|
||||
powCount = preferences.getLong(PREFERENCE_POW_COUNT, 0L)
|
||||
}
|
||||
}
|
||||
return (BigInteger.valueOf(averagePowUnitTime) * BigInteger(target) / TWO_POW_64).toLong()
|
||||
return (averagePowUnitTime * BigInteger(target) / TWO_POW_64).toLong()
|
||||
}
|
||||
|
||||
fun addPow(ctx: Context, time: Long, target: ByteArray) {
|
||||
@ -32,7 +32,7 @@ object PowStats {
|
||||
synchronized(this) {
|
||||
powCount++
|
||||
averagePowUnitTime = (
|
||||
(BigInteger.valueOf(averagePowUnitTime) * powCountBefore + (BigInteger.valueOf(time) * TWO_POW_64 / targetBigInt)) / BigInteger.valueOf(powCount)
|
||||
(averagePowUnitTime * powCountBefore + (time * TWO_POW_64 / targetBigInt)) / powCount
|
||||
).toLong()
|
||||
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(ctx)
|
||||
@ -42,4 +42,7 @@ object PowStats {
|
||||
.apply()
|
||||
}
|
||||
}
|
||||
|
||||
private operator fun Long.times(other: BigInteger) = this.toBigInteger() * other
|
||||
private operator fun BigInteger.div(other: Long) = this / other.toBigInteger()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user