Improve utilities

This commit is contained in:
Christian Basler 2018-03-23 17:50:43 +01:00
parent 46e5bb7ece
commit 49e77199b0
17 changed files with 194 additions and 180 deletions

View File

@ -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())
}
}

View File

@ -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)

View File

@ -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

View File

@ -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) {

View File

@ -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"

View File

@ -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

View File

@ -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 -> {

View File

@ -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)

View File

@ -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]

View File

@ -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,

View File

@ -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))

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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) {

View File

@ -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()
}