mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-24 16:57:50 +00:00
Implement linked devices screen redesign
This commit is contained in:
parent
38f3c3cff6
commit
7424684c75
@ -160,6 +160,8 @@
|
|||||||
android:name="org.thoughtcrime.securesms.loki.redesign.activities.NotificationSettingsActivity" />
|
android:name="org.thoughtcrime.securesms.loki.redesign.activities.NotificationSettingsActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name="org.thoughtcrime.securesms.loki.redesign.activities.ChatSettingsActivity" />
|
android:name="org.thoughtcrime.securesms.loki.redesign.activities.ChatSettingsActivity" />
|
||||||
|
<activity
|
||||||
|
android:name="org.thoughtcrime.securesms.loki.redesign.activities.LinkedDevicesActivity" />
|
||||||
<!-- Session -->
|
<!-- Session -->
|
||||||
<activity android:name="org.thoughtcrime.securesms.loki.LinkedDevicesActivity" />
|
<activity android:name="org.thoughtcrime.securesms.loki.LinkedDevicesActivity" />
|
||||||
<activity
|
<activity
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24">
|
android:viewportHeight="24">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FF000000"
|
android:fillColor="#FFFFFF"
|
||||||
android:pathData="M22,11.2l-9.2,0l0,-9.2l-1.6,0l0,9.2l-9.2,0l0,1.6l9.2,0l0,9.2l1.6,0l0,-9.2l9.2,0z"/>
|
android:pathData="M22,11.2l-9.2,0l0,-9.2l-1.6,0l0,9.2l-9.2,0l0,1.6l9.2,0l0,9.2l1.6,0l0,-9.2l9.2,0z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:shape="rectangle">
|
android:shape="rectangle">
|
||||||
|
|
||||||
<solid android:color="@color/unimportant_dialog_button_background" />
|
<solid android:color="@color/accent" />
|
||||||
|
|
||||||
<corners android:radius="@dimen/dialog_button_corner_radius" />
|
<corners android:radius="@dimen/dialog_button_corner_radius" />
|
||||||
|
|
||||||
<stroke android:width="@dimen/border_thickness" android:color="@color/unimportant_dialog_button_background" />
|
<stroke android:width="@dimen/border_thickness" android:color="@color/accent" />
|
||||||
</shape>
|
</shape>
|
37
res/layout/activity_linked_devices.xml
Normal file
37
res/layout/activity_linked_devices.xml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/default_session_background">
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_centerInParent="true">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="@dimen/medium_font_size"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:text="You don't have any linked devices yet" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/MediumProminentOutlineButton"
|
||||||
|
android:id="@+id/linkDeviceButton"
|
||||||
|
android:layout_width="196dp"
|
||||||
|
android:layout_height="@dimen/medium_button_height"
|
||||||
|
android:layout_marginTop="@dimen/medium_spacing"
|
||||||
|
android:text="Link a Device" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
85
res/layout/dialog_link_device_master_mode.xml
Normal file
85
res/layout/dialog_link_device_master_mode.xml
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?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="match_parent"
|
||||||
|
android:background="@drawable/default_dialog_background_inset"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="32dp"
|
||||||
|
android:paddingTop="@dimen/medium_spacing"
|
||||||
|
android:paddingRight="32dp"
|
||||||
|
android:paddingBottom="@dimen/medium_spacing">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/small_spacing"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/qrCodeImageView"
|
||||||
|
android:layout_width="128dp"
|
||||||
|
android:layout_height="128dp" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:text="Waiting for Device"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="@dimen/medium_font_size" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/explanationTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:text="Create a new account on your other device and click "Link to an existing account" to start the linking process"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:alpha="0.6"
|
||||||
|
android:textSize="@dimen/small_font_size"
|
||||||
|
android:textAlignment="center" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/mnemonicTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:text="puffin circle idled"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/small_font_size"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/large_spacing"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/UnimportantDialogButton"
|
||||||
|
android:id="@+id/cancelButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Cancel" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/ProminentDialogButton"
|
||||||
|
android:id="@+id/authorizeButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="@dimen/small_button_height"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginLeft="@dimen/medium_spacing"
|
||||||
|
android:text="Authorize"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
12
res/menu/menu_linked_devices.xml
Normal file
12
res/menu/menu_linked_devices.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/linkDeviceButton"
|
||||||
|
android:title="Link Device"
|
||||||
|
android:icon="@drawable/ic_plus_24"
|
||||||
|
app:showAsAction="always" />
|
||||||
|
|
||||||
|
</menu>
|
@ -0,0 +1,63 @@
|
|||||||
|
package org.thoughtcrime.securesms.loki.redesign.activities
|
||||||
|
|
||||||
|
import android.os.AsyncTask
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v7.widget.LinearLayoutManager
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import kotlinx.android.synthetic.main.activity_linked_devices.*
|
||||||
|
import network.loki.messenger.R
|
||||||
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||||
|
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 {
|
||||||
|
|
||||||
|
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.layoutManager = LinearLayoutManager(this)
|
||||||
|
linkDeviceButton.setOnClickListener { linkDevice() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
|
menuInflater.inflate(R.menu.menu_linked_devices, menu)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
val id = item.itemId
|
||||||
|
when (id) {
|
||||||
|
R.id.linkDeviceButton -> linkDevice()
|
||||||
|
else -> { /* Do nothing */ }
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun linkDevice() {
|
||||||
|
val linkDeviceDialog = LinkDeviceMasterModeDialog()
|
||||||
|
linkDeviceDialog.delegate = this
|
||||||
|
linkDeviceDialog.show(supportFragmentManager, "Link Device Dialog")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDeviceLinkRequestAuthorized(authorization: PairingAuthorisation) {
|
||||||
|
AsyncTask.execute {
|
||||||
|
signAndSendPairingAuthorisationMessage(this, authorization)
|
||||||
|
Util.runOnMain {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDeviceLinkCanceled() {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
@ -90,6 +90,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
privacyButton.setOnClickListener { showPrivacySettings() }
|
privacyButton.setOnClickListener { showPrivacySettings() }
|
||||||
notificationsButton.setOnClickListener { showNotificationSettings() }
|
notificationsButton.setOnClickListener { showNotificationSettings() }
|
||||||
chatsButton.setOnClickListener { showChatSettings() }
|
chatsButton.setOnClickListener { showChatSettings() }
|
||||||
|
linkedDevicesButton.setOnClickListener { showLinkedDevices() }
|
||||||
seedButton.setOnClickListener { showSeed() }
|
seedButton.setOnClickListener { showSeed() }
|
||||||
clearAllDataButton.setOnClickListener { clearAllData() }
|
clearAllDataButton.setOnClickListener { clearAllData() }
|
||||||
}
|
}
|
||||||
@ -265,6 +266,11 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
push(intent)
|
push(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showLinkedDevices() {
|
||||||
|
val intent = Intent(this, LinkedDevicesActivity::class.java)
|
||||||
|
push(intent)
|
||||||
|
}
|
||||||
|
|
||||||
private fun showSeed() {
|
private fun showSeed() {
|
||||||
SeedDialog().show(supportFragmentManager, "Recovery Phrase Dialog")
|
SeedDialog().show(supportFragmentManager, "Recovery Phrase Dialog")
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,87 @@
|
|||||||
|
package org.thoughtcrime.securesms.loki.redesign.dialogs
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.drawable.ColorDrawable
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.support.v4.app.DialogFragment
|
||||||
|
import android.support.v7.app.AlertDialog
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import kotlinx.android.synthetic.main.dialog_link_device_master_mode.view.*
|
||||||
|
import network.loki.messenger.R
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
|
import org.thoughtcrime.securesms.loki.MnemonicUtilities
|
||||||
|
import org.thoughtcrime.securesms.loki.redesign.utilities.QRCodeUtilities
|
||||||
|
import org.thoughtcrime.securesms.loki.toPx
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
|
import org.thoughtcrime.securesms.util.Util
|
||||||
|
import org.whispersystems.signalservice.loki.api.DeviceLinkingSession
|
||||||
|
import org.whispersystems.signalservice.loki.api.DeviceLinkingSessionListener
|
||||||
|
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
|
||||||
|
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
||||||
|
|
||||||
|
class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListener {
|
||||||
|
private val languageFileDirectory by lazy { MnemonicUtilities.getLanguageFileDirectory(context!!) }
|
||||||
|
private lateinit var contentView: View
|
||||||
|
private var authorization: PairingAuthorisation? = null
|
||||||
|
var delegate: LinkDeviceMasterModeDialogDelegate? = null
|
||||||
|
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
val builder = AlertDialog.Builder(context!!)
|
||||||
|
contentView = LayoutInflater.from(context!!).inflate(R.layout.dialog_link_device_master_mode, null)
|
||||||
|
val size = toPx(128, resources)
|
||||||
|
val hexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context!!)
|
||||||
|
val qrCode = QRCodeUtilities.encode(hexEncodedPublicKey, size)
|
||||||
|
contentView.qrCodeImageView.setImageBitmap(qrCode)
|
||||||
|
contentView.cancelButton.setOnClickListener { onDeviceLinkCanceled() }
|
||||||
|
contentView.authorizeButton.setOnClickListener { authorizeDeviceLink() }
|
||||||
|
builder.setView(contentView)
|
||||||
|
DeviceLinkingSession.shared.startListeningForLinkingRequests() // FIXME: This flag is named poorly as it's actually also used for authorizations
|
||||||
|
DeviceLinkingSession.shared.addListener(this)
|
||||||
|
val result = builder.create()
|
||||||
|
result.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun requestUserAuthorization(authorization: PairingAuthorisation) {
|
||||||
|
if (authorization.type != PairingAuthorisation.Type.REQUEST || authorization.primaryDevicePublicKey != TextSecurePreferences.getLocalNumber(context!!) || this.authorization != null) { return }
|
||||||
|
Util.runOnMain {
|
||||||
|
this.authorization = authorization
|
||||||
|
contentView.qrCodeImageView.visibility = View.GONE
|
||||||
|
val titleTextViewLayoutParams = contentView.titleTextView.layoutParams as LinearLayout.LayoutParams
|
||||||
|
titleTextViewLayoutParams.topMargin = toPx(8, resources)
|
||||||
|
contentView.titleTextView.layoutParams = titleTextViewLayoutParams
|
||||||
|
contentView.titleTextView.text = "Linking Request Received"
|
||||||
|
contentView.explanationTextView.text = "Please check that the words below match those shown on your other device"
|
||||||
|
contentView.mnemonicTextView.visibility = View.VISIBLE
|
||||||
|
contentView.mnemonicTextView.text = MnemonicUtilities.getFirst3Words(MnemonicCodec(languageFileDirectory), authorization.secondaryDevicePublicKey)
|
||||||
|
contentView.authorizeButton.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun authorizeDeviceLink() {
|
||||||
|
val authorization = this.authorization ?: return
|
||||||
|
delegate?.onDeviceLinkRequestAuthorized(authorization)
|
||||||
|
DeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
||||||
|
DeviceLinkingSession.shared.removeListener(this)
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onDeviceLinkCanceled() {
|
||||||
|
DeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
||||||
|
DeviceLinkingSession.shared.removeListener(this)
|
||||||
|
if (authorization != null) {
|
||||||
|
DatabaseFactory.getLokiPreKeyBundleDatabase(context).removePreKeyBundle(authorization!!.secondaryDevicePublicKey)
|
||||||
|
}
|
||||||
|
dismiss()
|
||||||
|
delegate?.onDeviceLinkCanceled()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LinkDeviceMasterModeDialogDelegate {
|
||||||
|
|
||||||
|
fun onDeviceLinkRequestAuthorized(authorization: PairingAuthorisation)
|
||||||
|
fun onDeviceLinkCanceled()
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user