Partially fix device linking

This commit is contained in:
Niels Andriesse 2020-01-17 11:38:30 +11:00
parent 0b8a21f37b
commit e95e39fdc9
6 changed files with 182 additions and 6 deletions

View File

@ -11,6 +11,7 @@
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/emptyStateContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/conversation_view_background"
android:padding="@dimen/medium_spacing"
android:orientation="vertical">
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textSize="@dimen/medium_font_size"
android:textStyle="bold"
android:textColor="@color/text"
android:text="Spiderman" />
<TextView
android:id="@+id/subtitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textSize="@dimen/small_font_size"
android:textColor="@color/text"
android:text="Sorry, gotta go fight crime again" />
</LinearLayout>

View File

@ -2,37 +2,67 @@ package org.thoughtcrime.securesms.loki.redesign.activities
import android.os.AsyncTask
import android.os.Bundle
import android.support.v4.app.LoaderManager
import android.support.v4.content.Loader
import android.support.v7.app.AlertDialog
import android.support.v7.widget.LinearLayoutManager
import android.view.Menu
import android.view.MenuItem
import android.view.View
import kotlinx.android.synthetic.main.activity_linked_devices.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.devicelist.Device
import org.thoughtcrime.securesms.loki.redesign.dialogs.LinkDeviceMasterModeDialog
import org.thoughtcrime.securesms.loki.redesign.dialogs.LinkDeviceMasterModeDialogDelegate
import org.thoughtcrime.securesms.loki.signAndSendPairingAuthorisationMessage
import org.thoughtcrime.securesms.util.Util
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LinkDeviceMasterModeDialogDelegate {
class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager.LoaderCallbacks<List<Device>>, LinkDeviceMasterModeDialogDelegate {
private val linkedDevicesAdapter = LinkedDevicesAdapter(this)
private var devices = listOf<Device>()
set(value) { field = value; linkedDevicesAdapter.devices = value }
// region Lifecycle
constructor() : super()
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
super.onCreate(savedInstanceState, isReady)
setContentView(R.layout.activity_linked_devices)
supportActionBar!!.title = "Linked Devices"
// val homeAdapter = LinkedDevicesAdapter(this, cursor)
// recyclerView.adapter = homeAdapter
recyclerView.adapter = linkedDevicesAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
linkDeviceButton.setOnClickListener { linkDevice() }
LoaderManager.getInstance(this).initLoader(0, null, this)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_linked_devices, menu)
return true
}
// endregion
// region Updating
override fun onCreateLoader(id: Int, bundle: Bundle?): Loader<List<Device>> {
return LinkedDevicesLoader(this)
}
override fun onLoadFinished(loader: Loader<List<Device>>, devices: List<Device>?) {
update(devices ?: listOf())
}
override fun onLoaderReset(loader: Loader<List<Device>>) {
update(listOf())
}
private fun update(devices: List<Device>) {
this.devices = devices
emptyStateContainer.visibility = if (devices.isEmpty()) View.VISIBLE else View.GONE
}
// endregion
// region Interaction
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
when (id) {
@ -43,9 +73,17 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LinkDeviceMas
}
private fun linkDevice() {
val linkDeviceDialog = LinkDeviceMasterModeDialog()
linkDeviceDialog.delegate = this
linkDeviceDialog.show(supportFragmentManager, "Link Device Dialog")
if (devices.isEmpty()) {
val linkDeviceDialog = LinkDeviceMasterModeDialog()
linkDeviceDialog.delegate = this
linkDeviceDialog.show(supportFragmentManager, "Link Device Dialog")
} else {
val builder = AlertDialog.Builder(this)
builder.setTitle("Multi Device Limit Reached")
builder.setMessage("It's currently not allowed to link more than one device.")
builder.setPositiveButton("OK", { dialog, _ -> dialog.dismiss() })
builder.create().show()
}
}
override fun onDeviceLinkRequestAuthorized(authorization: PairingAuthorisation) {
@ -60,4 +98,5 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LinkDeviceMas
override fun onDeviceLinkCanceled() {
// Do nothing
}
// endregion
}

View File

@ -0,0 +1,28 @@
package org.thoughtcrime.securesms.loki.redesign.activities
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.ViewGroup
import org.thoughtcrime.securesms.devicelist.Device
import org.thoughtcrime.securesms.loki.redesign.views.DeviceView
class LinkedDevicesAdapter(private val context: Context) : RecyclerView.Adapter<LinkedDevicesAdapter.ViewHolder>() {
var devices = listOf<Device>()
set(value) { field = value; notifyDataSetChanged() }
class ViewHolder(val view: DeviceView) : RecyclerView.ViewHolder(view)
override fun getItemCount(): Int {
return devices.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = DeviceView(context)
return ViewHolder(view)
}
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
val device = devices[position]
viewHolder.view.bind(device)
}
}

View File

@ -0,0 +1,33 @@
package org.thoughtcrime.securesms.loki.redesign.activities
import android.content.Context
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.devicelist.Device
import org.thoughtcrime.securesms.loki.MnemonicUtilities
import org.thoughtcrime.securesms.util.AsyncLoader
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
import java.io.File
class LinkedDevicesLoader(context: Context) : AsyncLoader<List<Device>>(context) {
private val mnemonicCodec by lazy {
val languageFileDirectory = File(context.applicationInfo.dataDir)
MnemonicCodec(languageFileDirectory)
}
override fun loadInBackground(): List<Device>? {
try {
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
val slaveDeviceHexEncodedPublicKeys = LokiStorageAPI.shared.getSecondaryDevicePublicKeys(userHexEncodedPublicKey).get()
return slaveDeviceHexEncodedPublicKeys.map { hexEncodedPublicKey ->
val shortID = MnemonicUtilities.getFirst3Words(mnemonicCodec, hexEncodedPublicKey)
val name = DatabaseFactory.getLokiUserDatabase(context).getDisplayName(hexEncodedPublicKey)
Device(hexEncodedPublicKey, shortID, name)
}.sortedBy { it.name }
} catch (e: Exception) {
return null
}
}
}

View File

@ -0,0 +1,44 @@
package org.thoughtcrime.securesms.loki.redesign.views
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.view_device.view.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.devicelist.Device
class DeviceView : LinearLayout {
var device: Device? = null
// region Lifecycle
constructor(context: Context) : super(context) {
setUpViewHierarchy()
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
setUpViewHierarchy()
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
setUpViewHierarchy()
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
setUpViewHierarchy()
}
private fun setUpViewHierarchy() {
val inflater = context.applicationContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val contentView = inflater.inflate(R.layout.view_device, null)
addView(contentView)
}
// endregion
// region Updating
fun bind(device: Device) {
titleTextView.text = if (!device.name.isNullOrBlank()) device.name else "Unnamed Device"
subtitleTextView.text = device.shortId
}
// endregion
}