Partially implement device linking redesign & fix copy
parent
7da4f1f6ae
commit
df61cbb30d
@ -1,7 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<set
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:anim/decelerate_interpolator">
|
||||
|
||||
<translate
|
||||
android:duration="350"
|
||||
android:fromYDelta="100%"
|
||||
android:toYDelta="0%" />
|
||||
android:duration="250"
|
||||
android:fromYDelta="100%"
|
||||
android:toYDelta="0%" />
|
||||
|
||||
</set>
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.v4.view.ViewPager
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<android.support.design.widget.TabLayout
|
||||
style="@style/Session.DarkTabLayout"
|
||||
android:id="@+id/tabLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/tab_bar_height" />
|
||||
|
||||
</android.support.v4.view.ViewPager>
|
@ -0,0 +1,63 @@
|
||||
<?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"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
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">
|
||||
|
||||
<com.github.ybq.android.spinkit.SpinKitView
|
||||
style="@style/SpinKitView.DoubleBounce"
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_centerInParent="true"
|
||||
app:SpinKit_Color="@color/text" />
|
||||
|
||||
<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 Authorization"
|
||||
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="Please check that the words below match those shown on your other device."
|
||||
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="@dimen/large_spacing"
|
||||
android:text="puffin circle idled"
|
||||
android:textColor="@color/text"
|
||||
android:textSize="@dimen/small_font_size"
|
||||
android:textAlignment="center" />
|
||||
|
||||
<Button
|
||||
style="@style/UnimportantDialogButton"
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/small_button_height"
|
||||
android:layout_marginTop="@dimen/large_spacing"
|
||||
android:text="Cancel" />
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,59 @@
|
||||
<?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_session_background"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/large_spacing"
|
||||
android:layout_marginRight="@dimen/large_spacing"
|
||||
android:textSize="@dimen/very_large_font_size"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/text"
|
||||
android:text="Link your device" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/large_spacing"
|
||||
android:layout_marginTop="@dimen/medium_spacing"
|
||||
android:layout_marginRight="@dimen/large_spacing"
|
||||
android:textSize="@dimen/medium_font_size"
|
||||
android:textColor="@color/text"
|
||||
android:text="Enter your Session ID to start the linking process." />
|
||||
|
||||
<EditText
|
||||
style="@style/SessionEditText"
|
||||
android:id="@+id/sessionIDEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/large_spacing"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginRight="@dimen/large_spacing"
|
||||
android:hint="Enter your session ID" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<Button
|
||||
style="@style/MediumProminentOutlineButton"
|
||||
android:id="@+id/requestDeviceLinkButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/medium_button_height"
|
||||
android:layout_marginLeft="90dp"
|
||||
android:layout_marginRight="90dp"
|
||||
android:layout_marginBottom="@dimen/medium_spacing"
|
||||
android:text="Next" />
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,103 @@
|
||||
package org.thoughtcrime.securesms.loki.redesign.activities
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.Fragment
|
||||
import android.support.v4.app.FragmentPagerAdapter
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
import kotlinx.android.synthetic.main.activity_link_device.*
|
||||
import kotlinx.android.synthetic.main.fragment_enter_session_id.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragment
|
||||
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragmentDelegate
|
||||
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation
|
||||
|
||||
class LinkDeviceActivity : BaseActionBarActivity(), ScanQRCodeWrapperFragmentDelegate {
|
||||
private val adapter = LinkDeviceActivityAdapter(this)
|
||||
|
||||
// region Lifecycle
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
// Set content view
|
||||
setContentView(R.layout.activity_link_device)
|
||||
// Set title
|
||||
supportActionBar!!.title = "Link Device"
|
||||
// Set up view pager
|
||||
viewPager.adapter = adapter
|
||||
tabLayout.setupWithViewPager(viewPager)
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Interaction
|
||||
override fun handleQRCodeScanned(hexEncodedPublicKey: String) {
|
||||
requestDeviceLinkIfPossible(hexEncodedPublicKey)
|
||||
}
|
||||
|
||||
fun requestDeviceLinkIfPossible(hexEncodedPublicKey: String) {
|
||||
if (!PublicKeyValidation.isValid(hexEncodedPublicKey)) {
|
||||
Toast.makeText(this, "Invalid Session ID", Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
val intent = Intent()
|
||||
intent.putExtra("hexEncodedPublicKey", hexEncodedPublicKey)
|
||||
setResult(RESULT_OK, intent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
||||
// region Adapter
|
||||
private class LinkDeviceActivityAdapter(val activity: LinkDeviceActivity) : FragmentPagerAdapter(activity.supportFragmentManager) {
|
||||
|
||||
override fun getCount(): Int {
|
||||
return 2
|
||||
}
|
||||
|
||||
override fun getItem(index: Int): Fragment {
|
||||
return when (index) {
|
||||
0 -> EnterSessionIDFragment()
|
||||
1 -> {
|
||||
val result = ScanQRCodeWrapperFragment()
|
||||
result.delegate = activity
|
||||
result.message = "Link to your existing account by going into your in-app settings and clicking \"Linked Devices\""
|
||||
result
|
||||
}
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPageTitle(index: Int): CharSequence? {
|
||||
return when (index) {
|
||||
0 -> "Enter Session ID"
|
||||
1 -> "Scan QR Code"
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Enter Session ID Fragment
|
||||
class EnterSessionIDFragment : Fragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
return inflater.inflate(R.layout.fragment_enter_session_id, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
requestDeviceLinkButton.setOnClickListener { requestDeviceLinkIfPossible() }
|
||||
}
|
||||
|
||||
private fun requestDeviceLinkIfPossible() {
|
||||
val inputMethodManager = context!!.getSystemService(BaseActionBarActivity.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputMethodManager.hideSoftInputFromWindow(sessionIDEditText.windowToken, 0)
|
||||
val hexEncodedPublicKey = sessionIDEditText.text.trim().toString().toLowerCase()
|
||||
(activity!! as LinkDeviceActivity).requestDeviceLinkIfPossible(hexEncodedPublicKey)
|
||||
}
|
||||
}
|
||||
// endregion
|
@ -0,0 +1,76 @@
|
||||
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.os.Handler
|
||||
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_slave_mode.view.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.loki.MnemonicUtilities
|
||||
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 LinkDeviceSlaveModeDialog : DialogFragment(), DeviceLinkingSessionListener {
|
||||
private val languageFileDirectory by lazy { MnemonicUtilities.getLanguageFileDirectory(context!!) }
|
||||
private lateinit var contentView: View
|
||||
private var authorization: PairingAuthorisation? = null
|
||||
var delegate: LinkDeviceSlaveModeDialogDelegate? = null
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val builder = AlertDialog.Builder(context!!)
|
||||
contentView = LayoutInflater.from(context!!).inflate(R.layout.dialog_link_device_slave_mode, null)
|
||||
val hexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
|
||||
contentView.mnemonicTextView.text = MnemonicUtilities.getFirst3Words(MnemonicCodec(languageFileDirectory), hexEncodedPublicKey)
|
||||
contentView.cancelButton.setOnClickListener { onDeviceLinkCanceled() }
|
||||
builder.setView(contentView)
|
||||
DeviceLinkingSession.shared.startListeningForLinkingRequests()
|
||||
DeviceLinkingSession.shared.addListener(this)
|
||||
val result = builder.create()
|
||||
result.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
return result
|
||||
}
|
||||
|
||||
override fun onDeviceLinkRequestAuthorized(authorization: PairingAuthorisation) {
|
||||
if (authorization.type != PairingAuthorisation.Type.GRANT || authorization.secondaryDevicePublicKey != TextSecurePreferences.getLocalNumber(context!!) || this.authorization != null) { return }
|
||||
Util.runOnMain {
|
||||
this.authorization = authorization
|
||||
DeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
||||
DeviceLinkingSession.shared.removeListener(this)
|
||||
contentView.spinner.visibility = View.GONE
|
||||
val titleTextViewLayoutParams = contentView.titleTextView.layoutParams as LinearLayout.LayoutParams
|
||||
titleTextViewLayoutParams.topMargin = 0
|
||||
contentView.titleTextView.layoutParams = titleTextViewLayoutParams
|
||||
contentView.titleTextView.text = "Device Link Authorized"
|
||||
contentView.explanationTextView.text = "Your device has been linked successfully"
|
||||
contentView.mnemonicTextView.visibility = View.GONE
|
||||
contentView.cancelButton.visibility = View.GONE
|
||||
Handler().postDelayed({
|
||||
dismiss()
|
||||
delegate?.onDeviceLinkRequestAuthorized(authorization)
|
||||
}, 4000)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onDeviceLinkCanceled() {
|
||||
DeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
||||
DeviceLinkingSession.shared.removeListener(this)
|
||||
dismiss()
|
||||
delegate?.onDeviceLinkCanceled()
|
||||
}
|
||||
}
|
||||
|
||||
interface LinkDeviceSlaveModeDialogDelegate {
|
||||
|
||||
fun onDeviceLinkRequestAuthorized(authorization: PairingAuthorisation)
|
||||
fun onDeviceLinkCanceled()
|
||||
}
|
Loading…
Reference in New Issue