Update app icon & implement recovery phrase screen
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 18 KiB |
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<solid android:color="@color/accent" />
|
||||||
|
</shape>
|
@ -1,11 +1,15 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="108dp"
|
android:width="108dp"
|
||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
android:viewportWidth="2041.7386"
|
android:viewportWidth="1018.39685"
|
||||||
android:viewportHeight="2041.9318">
|
android:viewportHeight="1019.1061">
|
||||||
<group android:translateX="492.4193"
|
<group android:translateX="307.15576"
|
||||||
android:translateY="520.9659">
|
android:translateY="285.3497">
|
||||||
<path android:fillColor="#FFFFFF" android:pathData="M480,730.8l-358.6,-358.5l371.8,-371.8l99,99.1l-272.6,272.7l259.4,259.5z"/>
|
<group>
|
||||||
<path android:fillColor="#FFFFFF" android:pathData="M563.7,999.5l-99.1,-99.1l272.7,-272.7l-259.5,-259.5l99.1,-99l358.5,358.5z"/>
|
<clip-path android:pathData="M0,0L404.085,0L404.085,448.407L0,448.407Z M 0,0"/>
|
||||||
|
<path android:fillAlpha="1" android:fillColor="#00f782"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="m288.607,420.376l-196.335,-0c-33.576,-0 -62.508,-25.748 -64.164,-59.281 -1.771,-35.847 26.883,-65.576 62.353,-65.576l113.072,-0c6.919,-0 12.527,-5.608 12.527,-12.525l0,-92.305L327.307,252.333C356.723,268.633 375.241,299.335 376.027,332.848 377.161,380.975 336.746,420.376 288.607,420.376m-211.829,-224.303c-29.416,-16.3 -47.933,-47.001 -48.721,-80.515 -1.132,-48.127 39.283,-87.528 87.42,-87.528L311.811,28.031c33.576,-0 62.508,25.748 64.165,59.283 1.771,35.845 -26.883,65.575 -62.352,65.575 0,-0 -81.316,0.013 -113.077,0.019 -6.915,0.001 -12.499,5.608 -12.501,12.523l-0.021,92.289zM340.891,227.816 L256.254,180.919l57.371,-0c49.877,-0 90.46,-40.579 90.46,-90.457 0,-49.877 -40.583,-90.461 -90.46,-90.461l-200.299,-0c-62.485,-0 -113.327,50.841 -113.327,113.327 0,44.567 24.216,85.664 63.195,107.265l84.636,46.896l-57.368,-0c-49.88,-0 -90.463,40.58 -90.463,90.457 0,49.877 40.583,90.461 90.463,90.461L290.758,448.407c62.488,-0 113.327,-50.84 113.327,-113.327 0,-44.567 -24.216,-85.664 -63.193,-107.264" android:strokeColor="#00000000"/>
|
||||||
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</vector>
|
</vector>
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
<?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">
|
||||||
|
|
||||||
|
<org.thoughtcrime.securesms.loki.redesign.views.SeedReminderView
|
||||||
|
android:id="@+id/seedReminderView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<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/very_large_spacing"
|
||||||
|
android:layout_marginRight="@dimen/very_large_spacing"
|
||||||
|
android:textSize="@dimen/very_large_font_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:text="Meet your recovery phrase" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/very_large_spacing"
|
||||||
|
android:layout_marginTop="@dimen/medium_spacing"
|
||||||
|
android:layout_marginRight="@dimen/very_large_spacing"
|
||||||
|
android:textSize="@dimen/medium_font_size"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:text="Think of this as the crypto-equivalent of a social security number. This allows whomever has it complete access to your account." />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/SessionIDTextView"
|
||||||
|
android:id="@+id/seedTextView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/very_large_spacing"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginRight="@dimen/very_large_spacing"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="@dimen/medium_font_size"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:text="nautical novelty populate onion awkward bent etiquette plant submarine itches vipers september axis maximum populate" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/revealButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/medium_spacing"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="@dimen/medium_font_size"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:alpha="0.6"
|
||||||
|
android:text="Hold to reveal" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/MediumProminentOutlineButton"
|
||||||
|
android:id="@+id/copyButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/medium_button_height"
|
||||||
|
android:layout_marginLeft="@dimen/massive_spacing"
|
||||||
|
android:layout_marginRight="@dimen/massive_spacing"
|
||||||
|
android:layout_marginBottom="@dimen/medium_spacing"
|
||||||
|
android:text="Copy" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -0,0 +1,73 @@
|
|||||||
|
<?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="@color/cell_background"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/accent_line_thickness"
|
||||||
|
android:paddingLeft="-2dp"
|
||||||
|
android:paddingRight="-2dp"
|
||||||
|
android:progressTint="@color/accent"
|
||||||
|
android:progressBackgroundTint="@color/progress_bar_background"
|
||||||
|
android:progress="80" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="@dimen/medium_spacing"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/small_font_size"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="You're almost finished! 80%" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/subtitleTextView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:textColor="@color/text"
|
||||||
|
android:textSize="@dimen/very_small_font_size"
|
||||||
|
android:alpha="0.6"
|
||||||
|
android:text="Secure your account by saving your recovery phrase" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style="@style/MediumProminentOutlineButton"
|
||||||
|
android:id="@+id/button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="27dp"
|
||||||
|
android:layout_marginLeft="@dimen/small_spacing"
|
||||||
|
android:textStyle="normal"
|
||||||
|
android:text="Continue" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:background="@color/separator" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 988 B After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 11 KiB |
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="ic_launcher_background">#0A0A0A</color>
|
<color name="ic_launcher_background">#333132</color>
|
||||||
</resources>
|
</resources>
|
@ -0,0 +1,85 @@
|
|||||||
|
package org.thoughtcrime.securesms.loki.redesign.activities
|
||||||
|
|
||||||
|
import android.content.ClipData
|
||||||
|
import android.content.ClipboardManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.Spannable
|
||||||
|
import android.text.SpannableString
|
||||||
|
import android.text.style.ForegroundColorSpan
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.Toast
|
||||||
|
import kotlinx.android.synthetic.main.activity_seed_v2.*
|
||||||
|
import network.loki.messenger.R
|
||||||
|
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||||
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
|
import org.thoughtcrime.securesms.loki.getColorWithID
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
|
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
||||||
|
import org.whispersystems.signalservice.loki.utilities.hexEncodedPrivateKey
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class SeedActivity : BaseActionBarActivity() {
|
||||||
|
|
||||||
|
private val seed by lazy {
|
||||||
|
val languageFileDirectory = File(applicationInfo.dataDir)
|
||||||
|
var hexEncodedSeed = IdentityKeyUtil.retrieve(this, IdentityKeyUtil.lokiSeedKey)
|
||||||
|
if (hexEncodedSeed == null) {
|
||||||
|
hexEncodedSeed = IdentityKeyUtil.getIdentityKeyPair(this).hexEncodedPrivateKey // Legacy account
|
||||||
|
}
|
||||||
|
MnemonicCodec(languageFileDirectory).encode(hexEncodedSeed!!, MnemonicCodec.Language.Configuration.english)
|
||||||
|
}
|
||||||
|
|
||||||
|
// region Lifecycle
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_seed_v2)
|
||||||
|
supportActionBar!!.title = "Your Recovery Phrase"
|
||||||
|
val seedReminderViewTitle = SpannableString("You're almost finished! 90%")
|
||||||
|
seedReminderViewTitle.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, theme)), 24, 27, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
seedReminderView.title = seedReminderViewTitle
|
||||||
|
seedReminderView.subtitle = "Press the redacted words to view your recovery phrase and secure your account"
|
||||||
|
seedReminderView.setProgress(90, false)
|
||||||
|
seedReminderView.hideContinueButton()
|
||||||
|
var redactedSeed = seed
|
||||||
|
var index = 0
|
||||||
|
for (character in seed) {
|
||||||
|
if (character.isLetter()) {
|
||||||
|
redactedSeed = redactedSeed.replaceRange(index, index + 1, "▆")
|
||||||
|
}
|
||||||
|
index += 1
|
||||||
|
}
|
||||||
|
seedTextView.setTextColor(resources.getColorWithID(R.color.accent, theme))
|
||||||
|
seedTextView.text = redactedSeed
|
||||||
|
seedTextView.setOnLongClickListener { revealSeed(); true }
|
||||||
|
revealButton.setOnLongClickListener { revealSeed(); true }
|
||||||
|
copyButton.setOnClickListener { copySeed() }
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Updating
|
||||||
|
private fun revealSeed() {
|
||||||
|
val seedReminderViewTitle = SpannableString("Account secured! 100%")
|
||||||
|
seedReminderViewTitle.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, theme)), 17, 21, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
seedReminderView.title = seedReminderViewTitle
|
||||||
|
seedReminderView.subtitle = "Make sure to store your recovery phrase in a safe place"
|
||||||
|
seedReminderView.setProgress(100, true)
|
||||||
|
val seedTextViewLayoutParams = seedTextView.layoutParams as LinearLayout.LayoutParams
|
||||||
|
seedTextViewLayoutParams.height = seedTextView.height
|
||||||
|
seedTextView.layoutParams = seedTextViewLayoutParams
|
||||||
|
seedTextView.setTextColor(resources.getColorWithID(R.color.text, theme))
|
||||||
|
seedTextView.text = seed
|
||||||
|
TextSecurePreferences.setHasViewedSeed(this, true)
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Interaction
|
||||||
|
private fun copySeed() {
|
||||||
|
revealSeed()
|
||||||
|
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
val clip = ClipData.newPlainText("Seed", seed)
|
||||||
|
clipboard.primaryClip = clip
|
||||||
|
Toast.makeText(this, R.string.activity_register_public_key_copied_message, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package org.thoughtcrime.securesms.loki.redesign.views
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import kotlinx.android.synthetic.main.view_seed_reminder.view.*
|
||||||
|
import network.loki.messenger.R
|
||||||
|
|
||||||
|
class SeedReminderView : FrameLayout {
|
||||||
|
var title: CharSequence
|
||||||
|
get() = titleTextView.text
|
||||||
|
set(value) { titleTextView.text = value }
|
||||||
|
var subtitle: CharSequence
|
||||||
|
get() = subtitleTextView.text
|
||||||
|
set(value) { subtitleTextView.text = value }
|
||||||
|
var delegate: SeedReminderViewDelegate? = null
|
||||||
|
|
||||||
|
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_seed_reminder, null)
|
||||||
|
addView(contentView)
|
||||||
|
button.setOnClickListener { delegate?.handleSeedReminderViewContinueButtonTapped() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setProgress(progress: Int, isAnimated: Boolean) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
progressBar.setProgress(progress, isAnimated)
|
||||||
|
} else {
|
||||||
|
progressBar.progress = progress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hideContinueButton() {
|
||||||
|
button.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SeedReminderViewDelegate {
|
||||||
|
|
||||||
|
fun handleSeedReminderViewContinueButtonTapped()
|
||||||
|
}
|