mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-19 19:28:26 +00:00
Implement QR code screen redesign
This commit is contained in:
parent
c76335150c
commit
b56d19e865
@ -153,6 +153,9 @@
|
||||
<activity
|
||||
android:name="org.thoughtcrime.securesms.loki.redesign.activities.SettingsActivity"
|
||||
android:launchMode="singleTask" />
|
||||
<activity
|
||||
android:name="org.thoughtcrime.securesms.loki.redesign.activities.QRCodeActivity"
|
||||
android:launchMode="singleTask" />
|
||||
<!-- Session -->
|
||||
<activity android:name="org.thoughtcrime.securesms.loki.LinkedDevicesActivity" />
|
||||
<activity
|
||||
|
14
res/layout/activity_qr_code.xml
Normal file
14
res/layout/activity_qr_code.xml
Normal file
@ -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>
|
@ -115,6 +115,22 @@
|
||||
android:layout_height="1px"
|
||||
android:background="@color/separator" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/chatsButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/setting_button_height"
|
||||
android:background="@drawable/setting_button_background"
|
||||
android:textColor="@color/text"
|
||||
android:textSize="@dimen/medium_font_size"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:text="Chats" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:background="@color/separator" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/linkedDevicesButton"
|
||||
android:layout_width="match_parent"
|
||||
|
74
res/layout/fragment_view_my_qr_code.xml
Normal file
74
res/layout/fragment_view_my_qr_code.xml
Normal file
@ -0,0 +1,74 @@
|
||||
<?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" >
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/contentView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<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/massive_font_size"
|
||||
android:textColor="@color/text"
|
||||
android:textStyle="bold"
|
||||
android:textAlignment="center"
|
||||
android:text="Scan Me" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/very_large_spacing"
|
||||
android:layout_marginTop="@dimen/small_spacing"
|
||||
android:layout_marginRight="@dimen/very_large_spacing"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/qrCodeImageView"
|
||||
android:layout_width="320dp"
|
||||
android:layout_height="320dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/explanationTextView"
|
||||
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:textSize="@dimen/medium_font_size"
|
||||
android:textColor="@color/text"
|
||||
android:fontFamily="@font/space_mono_regular"
|
||||
android:textAlignment="center"
|
||||
android:text="This is your unique public QR code. Other users may scan this in order to begin a conversation with you." />
|
||||
|
||||
<Button
|
||||
style="@style/MediumUnimportantOutlineButton"
|
||||
android:id="@+id/shareButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/medium_button_height"
|
||||
android:layout_marginLeft="90dp"
|
||||
android:layout_marginTop="28dp"
|
||||
android:layout_marginRight="90dp"
|
||||
android:layout_marginBottom="@dimen/medium_spacing"
|
||||
android:text="Share" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</RelativeLayout>
|
@ -0,0 +1,131 @@
|
||||
package org.thoughtcrime.securesms.loki.redesign.activities
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.Fragment
|
||||
import android.support.v4.app.FragmentPagerAdapter
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.StyleSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import kotlinx.android.synthetic.main.activity_qr_code.*
|
||||
import kotlinx.android.synthetic.main.fragment_view_my_qr_code.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.conversation.ConversationActivity
|
||||
import org.thoughtcrime.securesms.database.Address
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase
|
||||
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragment
|
||||
import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragmentDelegate
|
||||
import org.thoughtcrime.securesms.loki.redesign.utilities.QRCodeUtilities
|
||||
import org.thoughtcrime.securesms.loki.toPx
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation
|
||||
|
||||
|
||||
class QRCodeActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperFragmentDelegate {
|
||||
private val adapter = QRCodeActivityAdapter(this)
|
||||
|
||||
// region Lifecycle
|
||||
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
|
||||
super.onCreate(savedInstanceState, isReady)
|
||||
// Set content view
|
||||
setContentView(R.layout.activity_qr_code)
|
||||
// Set title
|
||||
supportActionBar!!.title = "QR Code"
|
||||
// Set up view pager
|
||||
viewPager.adapter = adapter
|
||||
tabLayout.setupWithViewPager(viewPager)
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region Interaction
|
||||
override fun handleQRCodeScanned(hexEncodedPublicKey: String) {
|
||||
createPrivateChatIfPossible(hexEncodedPublicKey)
|
||||
}
|
||||
|
||||
fun createPrivateChatIfPossible(hexEncodedPublicKey: String) {
|
||||
if (!PublicKeyValidation.isValid(hexEncodedPublicKey)) { return Toast.makeText(this, "Invalid Session ID", Toast.LENGTH_SHORT).show() }
|
||||
val masterHexEncodedPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(this)
|
||||
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this)
|
||||
val targetHexEncodedPublicKey = if (hexEncodedPublicKey == masterHexEncodedPublicKey) userHexEncodedPublicKey else hexEncodedPublicKey
|
||||
val recipient = Recipient.from(this, Address.fromSerialized(targetHexEncodedPublicKey), true)
|
||||
val intent = Intent(this, ConversationActivity::class.java)
|
||||
intent.putExtra(ConversationActivity.ADDRESS_EXTRA, recipient.address)
|
||||
intent.putExtra(ConversationActivity.TEXT_EXTRA, getIntent().getStringExtra(ConversationActivity.TEXT_EXTRA))
|
||||
intent.setDataAndType(getIntent().data, getIntent().type)
|
||||
val existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient)
|
||||
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, existingThread)
|
||||
intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
||||
// region Adapter
|
||||
private class QRCodeActivityAdapter(val activity: QRCodeActivity) : FragmentPagerAdapter(activity.supportFragmentManager) {
|
||||
|
||||
override fun getCount(): Int {
|
||||
return 2
|
||||
}
|
||||
|
||||
override fun getItem(index: Int): Fragment {
|
||||
return when (index) {
|
||||
0 -> ViewMyQRCodeFragment()
|
||||
1 -> {
|
||||
val result = ScanQRCodeWrapperFragment()
|
||||
result.delegate = activity
|
||||
result.message = "Scan someone\'s QR code to start a conversation with them"
|
||||
result
|
||||
}
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPageTitle(index: Int): CharSequence? {
|
||||
return when (index) {
|
||||
0 -> "View My QR Code"
|
||||
1 -> "Scan QR Code"
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region View My QR Code Fragment
|
||||
class ViewMyQRCodeFragment : Fragment() {
|
||||
|
||||
private val hexEncodedPublicKey: String
|
||||
get() {
|
||||
val masterHexEncodedPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context!!)
|
||||
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context!!)
|
||||
return masterHexEncodedPublicKey ?: userHexEncodedPublicKey
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
return inflater.inflate(R.layout.fragment_view_my_qr_code, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val size = toPx(240, resources)
|
||||
val qrCode = QRCodeUtilities.encode(hexEncodedPublicKey, size)
|
||||
qrCodeImageView.setImageBitmap(qrCode)
|
||||
val explanation = SpannableStringBuilder("This is your unique public QR code. Other users may scan this in order to begin a conversation with you.")
|
||||
explanation.setSpan(StyleSpan(Typeface.BOLD), 8, 34, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
explanationTextView.text = explanation
|
||||
shareButton.setOnClickListener { shareQRCode() }
|
||||
}
|
||||
|
||||
private fun shareQRCode() {
|
||||
// TODO: Implement
|
||||
}
|
||||
}
|
||||
// endregion
|
@ -12,6 +12,7 @@ import kotlinx.android.synthetic.main.activity_settings.*
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.loki.redesign.utilities.push
|
||||
import org.thoughtcrime.securesms.mms.GlideApp
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
@ -67,7 +68,8 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
}
|
||||
|
||||
private fun showQRCode() {
|
||||
// TODO: Implement
|
||||
val intent = Intent(this, QRCodeActivity::class.java)
|
||||
push(intent)
|
||||
}
|
||||
|
||||
private fun copyPublicKey() {
|
||||
|
@ -35,7 +35,11 @@ class ScanQRCodeFragmentV2 : Fragment() {
|
||||
super.onResume()
|
||||
cameraView.onResume()
|
||||
cameraView.setPreviewCallback(scanningThread)
|
||||
scanningThread.start()
|
||||
try {
|
||||
scanningThread.start()
|
||||
} catch (exception: Exception) {
|
||||
// Do nothing
|
||||
}
|
||||
scanningThread.setScanListener(scanListener)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,31 @@
|
||||
package org.thoughtcrime.securesms.loki.redesign.utilities
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.EncodeHintType
|
||||
import com.google.zxing.WriterException
|
||||
import com.google.zxing.qrcode.QRCodeWriter
|
||||
|
||||
object QRCodeUtilities {
|
||||
|
||||
fun encode(data: String, size: Int, hasTransparentBackground: Boolean = true): Bitmap {
|
||||
try {
|
||||
val hints = hashMapOf( EncodeHintType.MARGIN to 1 )
|
||||
val result = QRCodeWriter().encode(data, BarcodeFormat.QR_CODE, size, size, hints)
|
||||
val bitmap = Bitmap.createBitmap(result.width, result.height, Bitmap.Config.ARGB_8888)
|
||||
for (y in 0 until result.height) {
|
||||
for (x in 0 until result.width) {
|
||||
if (result.get(x, y)) {
|
||||
bitmap.setPixel(x, y, Color.WHITE)
|
||||
} else if (!hasTransparentBackground) {
|
||||
bitmap.setPixel(x, y, Color.BLACK)
|
||||
}
|
||||
}
|
||||
}
|
||||
return bitmap
|
||||
} catch (e: WriterException) {
|
||||
return Bitmap.createBitmap(512, 512, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.loki.JazzIdenticonDrawable
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
||||
// TODO: Look into a better way of handling different sizes
|
||||
// TODO: Look into a better way of handling different sizes. Maybe an enum (with associated values) encapsulating the different modes?
|
||||
|
||||
class ProfilePictureView : RelativeLayout {
|
||||
lateinit var glide: GlideRequests
|
||||
|
Loading…
x
Reference in New Issue
Block a user