2021-07-09 05:56:38 +02:00
|
|
|
package org.thoughtcrime.securesms.dms
|
2019-12-18 11:36:09 +01:00
|
|
|
|
2021-05-27 07:31:48 +02:00
|
|
|
import android.animation.Animator
|
|
|
|
import android.animation.AnimatorListenerAdapter
|
2019-12-18 14:31:12 +01:00
|
|
|
import android.content.ClipData
|
|
|
|
import android.content.ClipboardManager
|
|
|
|
import android.content.Context
|
|
|
|
import android.content.Intent
|
2019-12-18 11:36:09 +01:00
|
|
|
import android.os.Bundle
|
2020-08-05 02:01:25 +02:00
|
|
|
import android.text.InputType
|
2021-06-02 03:34:30 +02:00
|
|
|
import android.util.TypedValue
|
2022-01-14 06:56:15 +01:00
|
|
|
import android.view.LayoutInflater
|
|
|
|
import android.view.View
|
|
|
|
import android.view.ViewGroup
|
2020-08-05 02:01:25 +02:00
|
|
|
import android.view.inputmethod.EditorInfo
|
|
|
|
import android.view.inputmethod.InputMethodManager
|
2019-12-18 14:31:12 +01:00
|
|
|
import android.widget.Toast
|
2021-06-02 03:34:30 +02:00
|
|
|
import androidx.core.view.isVisible
|
|
|
|
import androidx.fragment.app.Fragment
|
|
|
|
import androidx.fragment.app.FragmentPagerAdapter
|
2019-12-18 11:36:09 +01:00
|
|
|
import network.loki.messenger.R
|
2022-01-14 06:56:15 +01:00
|
|
|
import network.loki.messenger.databinding.ActivityCreatePrivateChatBinding
|
|
|
|
import network.loki.messenger.databinding.FragmentEnterPublicKeyBinding
|
2021-05-28 03:22:06 +02:00
|
|
|
import nl.komponents.kovenant.ui.failUi
|
2021-05-28 07:14:05 +02:00
|
|
|
import nl.komponents.kovenant.ui.successUi
|
2021-05-27 07:31:48 +02:00
|
|
|
import org.session.libsession.snode.SnodeAPI
|
2021-05-18 08:11:38 +02:00
|
|
|
import org.session.libsession.utilities.Address
|
2021-06-02 03:34:30 +02:00
|
|
|
import org.session.libsession.utilities.TextSecurePreferences
|
|
|
|
import org.session.libsession.utilities.recipients.Recipient
|
|
|
|
import org.session.libsignal.utilities.PublicKeyValidation
|
|
|
|
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
2021-06-30 06:57:53 +02:00
|
|
|
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
2021-10-04 09:51:19 +02:00
|
|
|
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
2021-07-09 05:56:38 +02:00
|
|
|
import org.thoughtcrime.securesms.util.ScanQRCodeWrapperFragment
|
|
|
|
import org.thoughtcrime.securesms.util.ScanQRCodeWrapperFragmentDelegate
|
2020-08-05 02:01:25 +02:00
|
|
|
|
2020-01-06 04:26:52 +01:00
|
|
|
class CreatePrivateChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperFragmentDelegate {
|
2022-01-14 06:56:15 +01:00
|
|
|
private lateinit var binding: ActivityCreatePrivateChatBinding
|
2019-12-18 15:25:23 +01:00
|
|
|
private val adapter = CreatePrivateChatActivityAdapter(this)
|
2021-06-02 03:34:30 +02:00
|
|
|
private var isKeyboardShowing = false
|
|
|
|
set(value) {
|
|
|
|
val hasChanged = (field != value)
|
|
|
|
field = value
|
|
|
|
if (hasChanged) {
|
|
|
|
adapter.isKeyboardShowing = value
|
|
|
|
}
|
|
|
|
}
|
2019-12-18 11:36:09 +01:00
|
|
|
|
|
|
|
// region Lifecycle
|
2020-01-06 04:26:52 +01:00
|
|
|
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
|
|
|
|
super.onCreate(savedInstanceState, isReady)
|
2022-01-14 06:56:15 +01:00
|
|
|
binding = ActivityCreatePrivateChatBinding.inflate(layoutInflater)
|
2019-12-18 11:36:09 +01:00
|
|
|
// Set content view
|
2022-01-14 06:56:15 +01:00
|
|
|
setContentView(binding.root)
|
2019-12-18 11:36:09 +01:00
|
|
|
// Set title
|
2020-05-25 08:12:24 +02:00
|
|
|
supportActionBar!!.title = resources.getString(R.string.activity_create_private_chat_title)
|
2019-12-18 11:36:09 +01:00
|
|
|
// Set up view pager
|
2022-01-14 06:56:15 +01:00
|
|
|
binding.viewPager.adapter = adapter
|
|
|
|
binding.tabLayout.setupWithViewPager(binding.viewPager)
|
|
|
|
binding.rootLayout.viewTreeObserver.addOnGlobalLayoutListener {
|
|
|
|
val diff = binding.rootLayout.rootView.height - binding.rootLayout.height
|
|
|
|
val displayMetrics = this@CreatePrivateChatActivity.resources.displayMetrics
|
|
|
|
val estimatedKeyboardHeight =
|
|
|
|
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200.0f, displayMetrics)
|
|
|
|
this@CreatePrivateChatActivity.isKeyboardShowing = (diff > estimatedKeyboardHeight)
|
|
|
|
}
|
2020-10-02 07:24:13 +02:00
|
|
|
}
|
2019-12-18 11:36:09 +01:00
|
|
|
// endregion
|
2019-12-18 14:31:12 +01:00
|
|
|
|
2021-05-27 07:31:48 +02:00
|
|
|
// region Updating
|
|
|
|
private fun showLoader() {
|
2022-01-14 06:56:15 +01:00
|
|
|
binding.loader.visibility = View.VISIBLE
|
|
|
|
binding.loader.animate().setDuration(150).alpha(1.0f).start()
|
2021-05-27 07:31:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private fun hideLoader() {
|
2022-01-14 06:56:15 +01:00
|
|
|
binding.loader.animate().setDuration(150).alpha(0.0f).setListener(object : AnimatorListenerAdapter() {
|
2021-05-27 07:31:48 +02:00
|
|
|
|
|
|
|
override fun onAnimationEnd(animation: Animator?) {
|
|
|
|
super.onAnimationEnd(animation)
|
2022-01-14 06:56:15 +01:00
|
|
|
binding.loader.visibility = View.GONE
|
2021-05-27 07:31:48 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
// endregion
|
|
|
|
|
2019-12-18 14:31:12 +01:00
|
|
|
// region Interaction
|
2019-12-18 15:25:23 +01:00
|
|
|
override fun handleQRCodeScanned(hexEncodedPublicKey: String) {
|
|
|
|
createPrivateChatIfPossible(hexEncodedPublicKey)
|
|
|
|
}
|
|
|
|
|
2021-05-27 07:31:48 +02:00
|
|
|
fun createPrivateChatIfPossible(onsNameOrPublicKey: String) {
|
2021-05-28 03:22:06 +02:00
|
|
|
if (PublicKeyValidation.isValid(onsNameOrPublicKey)) {
|
2021-05-27 07:31:48 +02:00
|
|
|
createPrivateChat(onsNameOrPublicKey)
|
|
|
|
} else {
|
|
|
|
// This could be an ONS name
|
|
|
|
showLoader()
|
2021-07-26 03:23:58 +02:00
|
|
|
SnodeAPI.getSessionID(onsNameOrPublicKey).successUi { hexEncodedPublicKey ->
|
2021-05-27 07:31:48 +02:00
|
|
|
hideLoader()
|
|
|
|
this.createPrivateChat(hexEncodedPublicKey)
|
2021-05-28 03:22:06 +02:00
|
|
|
}.failUi { exception ->
|
2021-05-27 07:31:48 +02:00
|
|
|
hideLoader()
|
2021-05-28 07:14:05 +02:00
|
|
|
var message = resources.getString(R.string.fragment_enter_public_key_error_message)
|
2021-05-27 07:31:48 +02:00
|
|
|
exception.localizedMessage?.let {
|
|
|
|
message = it
|
|
|
|
}
|
|
|
|
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun createPrivateChat(hexEncodedPublicKey: String) {
|
2021-02-18 05:12:30 +01:00
|
|
|
val recipient = Recipient.from(this, Address.fromSerialized(hexEncodedPublicKey), false)
|
2021-06-30 06:57:53 +02:00
|
|
|
val intent = Intent(this, ConversationActivityV2::class.java)
|
2021-07-01 01:31:30 +02:00
|
|
|
intent.putExtra(ConversationActivityV2.ADDRESS, recipient.address)
|
2019-12-18 14:31:12 +01:00
|
|
|
intent.setDataAndType(getIntent().data, getIntent().type)
|
2021-10-04 09:51:19 +02:00
|
|
|
val existingThread = DatabaseComponent.get(this).threadDatabase().getThreadIdIfExistsFor(recipient)
|
2021-06-30 06:57:53 +02:00
|
|
|
intent.putExtra(ConversationActivityV2.THREAD_ID, existingThread)
|
2019-12-18 14:31:12 +01:00
|
|
|
startActivity(intent)
|
|
|
|
finish()
|
|
|
|
}
|
|
|
|
// endregion
|
2019-12-18 11:36:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// region Adapter
|
2019-12-18 15:25:23 +01:00
|
|
|
private class CreatePrivateChatActivityAdapter(val activity: CreatePrivateChatActivity) : FragmentPagerAdapter(activity.supportFragmentManager) {
|
2020-10-02 07:24:13 +02:00
|
|
|
val enterPublicKeyFragment = EnterPublicKeyFragment()
|
2021-06-02 03:34:30 +02:00
|
|
|
var isKeyboardShowing = false
|
|
|
|
set(value) { field = value; enterPublicKeyFragment.isKeyboardShowing = isKeyboardShowing }
|
2019-12-18 11:36:09 +01:00
|
|
|
|
|
|
|
override fun getCount(): Int {
|
|
|
|
return 2
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getItem(index: Int): Fragment {
|
2019-12-18 14:31:12 +01:00
|
|
|
return when (index) {
|
2020-10-02 07:24:13 +02:00
|
|
|
0 -> enterPublicKeyFragment
|
2019-12-18 15:25:23 +01:00
|
|
|
1 -> {
|
|
|
|
val result = ScanQRCodeWrapperFragment()
|
|
|
|
result.delegate = activity
|
2020-05-25 08:12:24 +02:00
|
|
|
result.message = activity.resources.getString(R.string.activity_create_private_chat_scan_qr_code_explanation)
|
2019-12-18 15:25:23 +01:00
|
|
|
result
|
|
|
|
}
|
2019-12-18 14:31:12 +01:00
|
|
|
else -> throw IllegalStateException()
|
|
|
|
}
|
2019-12-18 11:36:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun getPageTitle(index: Int): CharSequence? {
|
|
|
|
return when (index) {
|
2020-05-25 08:12:24 +02:00
|
|
|
0 -> activity.resources.getString(R.string.activity_create_private_chat_enter_session_id_tab_title)
|
|
|
|
1 -> activity.resources.getString(R.string.activity_create_private_chat_scan_qr_code_tab_title)
|
2019-12-18 11:36:09 +01:00
|
|
|
else -> throw IllegalStateException()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// endregion
|
|
|
|
|
2019-12-18 14:31:12 +01:00
|
|
|
// region Enter Public Key Fragment
|
2019-12-18 11:36:09 +01:00
|
|
|
class EnterPublicKeyFragment : Fragment() {
|
2022-01-14 06:56:15 +01:00
|
|
|
private lateinit var binding: FragmentEnterPublicKeyBinding
|
|
|
|
|
2021-06-02 03:34:30 +02:00
|
|
|
var isKeyboardShowing = false
|
|
|
|
set(value) { field = value; handleIsKeyboardShowingChanged() }
|
2019-12-18 15:25:23 +01:00
|
|
|
|
2019-12-18 14:31:12 +01:00
|
|
|
private val hexEncodedPublicKey: String
|
|
|
|
get() {
|
2021-02-18 05:12:30 +01:00
|
|
|
return TextSecurePreferences.getLocalNumber(requireContext())!!
|
2019-12-18 14:31:12 +01:00
|
|
|
}
|
2019-12-18 11:36:09 +01:00
|
|
|
|
|
|
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
2022-01-14 06:56:15 +01:00
|
|
|
binding = FragmentEnterPublicKeyBinding.inflate(inflater, container, false)
|
|
|
|
return binding.root
|
2019-12-18 11:36:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
|
|
super.onViewCreated(view, savedInstanceState)
|
2022-01-14 06:56:15 +01:00
|
|
|
with(binding) {
|
|
|
|
publicKeyEditText.imeOptions = EditorInfo.IME_ACTION_DONE or 16777216 // Always use incognito keyboard
|
|
|
|
publicKeyEditText.setRawInputType(InputType.TYPE_CLASS_TEXT)
|
|
|
|
publicKeyEditText.setOnEditorActionListener { v, actionID, _ ->
|
|
|
|
if (actionID == EditorInfo.IME_ACTION_DONE) {
|
|
|
|
val imm = v.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
|
|
|
imm.hideSoftInputFromWindow(v.windowToken, 0)
|
|
|
|
createPrivateChatIfPossible()
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
2020-08-05 02:01:25 +02:00
|
|
|
}
|
2022-01-14 06:56:15 +01:00
|
|
|
publicKeyTextView.text = hexEncodedPublicKey
|
|
|
|
copyButton.setOnClickListener { copyPublicKey() }
|
|
|
|
shareButton.setOnClickListener { sharePublicKey() }
|
|
|
|
createPrivateChatButton.setOnClickListener { createPrivateChatIfPossible() }
|
2020-08-05 02:01:25 +02:00
|
|
|
}
|
2019-12-18 14:31:12 +01:00
|
|
|
}
|
|
|
|
|
2021-06-02 03:34:30 +02:00
|
|
|
private fun handleIsKeyboardShowingChanged() {
|
2022-01-14 06:56:15 +01:00
|
|
|
binding.optionalContentContainer.isVisible = !isKeyboardShowing
|
2021-06-02 03:34:30 +02:00
|
|
|
}
|
|
|
|
|
2019-12-18 14:31:12 +01:00
|
|
|
private fun copyPublicKey() {
|
2020-09-17 09:06:39 +02:00
|
|
|
val clipboard = requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
2019-12-18 14:31:12 +01:00
|
|
|
val clip = ClipData.newPlainText("Session ID", hexEncodedPublicKey)
|
2020-08-19 02:06:26 +02:00
|
|
|
clipboard.setPrimaryClip(clip)
|
2020-09-17 09:06:39 +02:00
|
|
|
Toast.makeText(requireContext(), R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show()
|
2019-12-18 14:31:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private fun sharePublicKey() {
|
|
|
|
val intent = Intent()
|
|
|
|
intent.action = Intent.ACTION_SEND
|
|
|
|
intent.putExtra(Intent.EXTRA_TEXT, hexEncodedPublicKey)
|
|
|
|
intent.type = "text/plain"
|
|
|
|
startActivity(intent)
|
|
|
|
}
|
|
|
|
|
2021-06-02 03:34:30 +02:00
|
|
|
private fun createPrivateChatIfPossible() {
|
2022-01-14 06:56:15 +01:00
|
|
|
val hexEncodedPublicKey = binding.publicKeyEditText.text?.trim().toString()
|
2021-06-02 03:34:30 +02:00
|
|
|
val activity = requireActivity() as CreatePrivateChatActivity
|
|
|
|
activity.createPrivateChatIfPossible(hexEncodedPublicKey)
|
2019-12-18 11:36:09 +01:00
|
|
|
}
|
2019-12-18 14:31:12 +01:00
|
|
|
}
|
|
|
|
// endregion
|