Remove BaseDialog and utilise dialog DSL

This commit is contained in:
andrew 2023-05-31 12:15:41 +09:30
parent 1d8d678047
commit 4e92c40210
19 changed files with 128 additions and 566 deletions

View File

@ -17,6 +17,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.core.view.setMargins import androidx.core.view.setMargins
import androidx.core.view.setPadding import androidx.core.view.setPadding
import androidx.core.view.updateMargins import androidx.core.view.updateMargins
import androidx.fragment.app.Fragment
import network.loki.messenger.R import network.loki.messenger.R
import org.thoughtcrime.securesms.util.toPx import org.thoughtcrime.securesms.util.toPx
@ -28,6 +29,9 @@ annotation class DialogDsl
@DialogDsl @DialogDsl
class SessionDialogBuilder(val context: Context) { class SessionDialogBuilder(val context: Context) {
val dp20 = toPx(20, context.resources)
val dp40 = toPx(40, context.resources)
private val dialogBuilder: AlertDialog.Builder = AlertDialog.Builder(context) private val dialogBuilder: AlertDialog.Builder = AlertDialog.Builder(context)
private var dialog: AlertDialog? = null private var dialog: AlertDialog? = null
@ -49,19 +53,19 @@ class SessionDialogBuilder(val context: Context) {
fun title(text: CharSequence?) = title(text?.toString()) fun title(text: CharSequence?) = title(text?.toString())
fun title(text: String?) { fun title(text: String?) {
text(text, R.style.TextAppearance_AppCompat_Title) { setPadding(toPx(20, resources)) } text(text, R.style.TextAppearance_AppCompat_Title) { setPadding(dp20) }
} }
fun text(@StringRes id: Int, style: Int = 0) = text(context.getString(id), style) fun text(@StringRes id: Int, style: Int = 0) = text(context.getString(id), style)
fun text(text: CharSequence?) = text(text?.toString()) fun text(text: CharSequence?, @StyleRes style: Int = 0) {
fun text(text: String?, @StyleRes style: Int = 0) {
text(text, style) { text(text, style) {
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT) layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
.apply { toPx(40, resources).let { updateMargins(it, 0, it, 0) } } .apply { updateMargins(dp40, 0, dp40, dp20) }
} }
} }
private fun text(text: String?, @StyleRes style: Int, modify: TextView.() -> Unit) {
private fun text(text: CharSequence?, @StyleRes style: Int, modify: TextView.() -> Unit) {
text ?: return text ?: return
TextView(context, null, 0, style) TextView(context, null, 0, style)
.apply { .apply {
@ -77,9 +81,15 @@ class SessionDialogBuilder(val context: Context) {
fun iconAttribute(@AttrRes icon: Int): AlertDialog.Builder = dialogBuilder.setIconAttribute(icon) fun iconAttribute(@AttrRes icon: Int): AlertDialog.Builder = dialogBuilder.setIconAttribute(icon)
fun singleChoiceItems(
options: Collection<String>,
currentSelected: Int = 0,
onSelect: (Int) -> Unit
) = singleChoiceItems(options.toTypedArray(), currentSelected, onSelect)
fun singleChoiceItems( fun singleChoiceItems(
options: Array<String>, options: Array<String>,
currentSelected: Int, currentSelected: Int = 0,
onSelect: (Int) -> Unit onSelect: (Int) -> Unit
): AlertDialog.Builder = dialogBuilder.setSingleChoiceItems( ): AlertDialog.Builder = dialogBuilder.setSingleChoiceItems(
options, options,
@ -101,7 +111,7 @@ class SessionDialogBuilder(val context: Context) {
fun button( fun button(
@StringRes text: Int, @StringRes text: Int,
@StringRes contentDescriptionRes: Int = 0, @StringRes contentDescriptionRes: Int = text,
@StyleRes style: Int = R.style.Widget_Session_Button_Dialog_UnimportantText, @StyleRes style: Int = R.style.Widget_Session_Button_Dialog_UnimportantText,
listener: (() -> Unit) = {} listener: (() -> Unit) = {}
) = Button(context, null, 0, style).apply { ) = Button(context, null, 0, style).apply {
@ -115,8 +125,12 @@ class SessionDialogBuilder(val context: Context) {
} }
}.let(buttonLayout::addView) }.let(buttonLayout::addView)
fun create(): AlertDialog = dialogBuilder.create()
fun show(): AlertDialog = dialogBuilder.show() fun show(): AlertDialog = dialogBuilder.show()
} }
fun Context.sessionDialog(build: SessionDialogBuilder.() -> Unit): AlertDialog = fun Context.sessionDialog(build: SessionDialogBuilder.() -> Unit): AlertDialog =
SessionDialogBuilder(this).apply { build() }.show() SessionDialogBuilder(this).apply { build() }.show()
fun Fragment.sessionDialog(build: SessionDialogBuilder.() -> Unit): AlertDialog =
SessionDialogBuilder(requireContext()).apply { build() }.create()

View File

@ -22,6 +22,7 @@ import androidx.activity.viewModels
import androidx.annotation.DimenRes import androidx.annotation.DimenRes
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -405,8 +406,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
push(intent, false) push(intent, false)
} }
override fun showDialog(baseDialog: BaseDialog, tag: String?) { override fun showDialog(dialogFragment: DialogFragment, tag: String?) {
baseDialog.show(supportFragmentManager, tag) dialogFragment.show(supportFragmentManager, tag)
} }
override fun onCreateLoader(id: Int, bundle: Bundle?): Loader<Cursor> { override fun onCreateLoader(id: Int, bundle: Bundle?): Loader<Cursor> {

View File

@ -1,41 +1,40 @@
package org.thoughtcrime.securesms.conversation.v2.dialogs package org.thoughtcrime.securesms.conversation.v2.dialogs
import android.app.Dialog
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Bundle
import android.text.Spannable import android.text.Spannable
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.style.StyleSpan import android.text.style.StyleSpan
import android.view.LayoutInflater import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.databinding.DialogBlockedBinding
import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.sessionDialog
/** Shown upon sending a message to a user that's blocked. */ /** Shown upon sending a message to a user that's blocked. */
class BlockedDialog(private val recipient: Recipient) : BaseDialog() { class BlockedDialog(private val recipient: Recipient) : DialogFragment() {
override fun setContentView(builder: AlertDialog.Builder) { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = sessionDialog {
val binding = DialogBlockedBinding.inflate(LayoutInflater.from(requireContext()))
val contactDB = DatabaseComponent.get(requireContext()).sessionContactDatabase() val contactDB = DatabaseComponent.get(requireContext()).sessionContactDatabase()
val sessionID = recipient.address.toString() val sessionID = recipient.address.toString()
val contact = contactDB.getContactWithSessionID(sessionID) val contact = contactDB.getContactWithSessionID(sessionID)
val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID
val title = resources.getString(R.string.dialog_blocked_title, name)
binding.blockedTitleTextView.text = title
val explanation = resources.getString(R.string.dialog_blocked_explanation, name) val explanation = resources.getString(R.string.dialog_blocked_explanation, name)
val spannable = SpannableStringBuilder(explanation) val spannable = SpannableStringBuilder(explanation)
val startIndex = explanation.indexOf(name) val startIndex = explanation.indexOf(name)
spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
binding.blockedExplanationTextView.text = spannable
binding.cancelButton.setOnClickListener { dismiss() } title(resources.getString(R.string.dialog_blocked_title, name))
binding.unblockButton.setOnClickListener { unblock() } text(spannable)
builder.setView(binding.root) button(R.string.ConversationActivity_unblock) { unblock() }
cancelButton { dismiss() }
} }
private fun unblock() { private fun unblock() {
DatabaseComponent.get(requireContext()).recipientDatabase().setBlocked(recipient, false) DatabaseComponent.get(requireContext()).recipientDatabase().setBlocked(recipient, false)
dismiss() dismiss()
} }
} }

View File

@ -1,45 +1,44 @@
package org.thoughtcrime.securesms.conversation.v2.dialogs package org.thoughtcrime.securesms.conversation.v2.dialogs
import android.app.Dialog
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Bundle
import android.text.Spannable import android.text.Spannable
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.style.StyleSpan import android.text.style.StyleSpan
import android.view.LayoutInflater import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.databinding.DialogDownloadBinding
import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.jobs.AttachmentDownloadJob import org.session.libsession.messaging.jobs.AttachmentDownloadJob
import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.JobQueue
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
import org.thoughtcrime.securesms.database.SessionContactDatabase import org.thoughtcrime.securesms.database.SessionContactDatabase
import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.sessionDialog
import javax.inject.Inject import javax.inject.Inject
/** Shown when receiving media from a contact for the first time, to confirm that /** Shown when receiving media from a contact for the first time, to confirm that
* they are to be trusted and files sent by them are to be downloaded. */ * they are to be trusted and files sent by them are to be downloaded. */
@AndroidEntryPoint @AndroidEntryPoint
class DownloadDialog(private val recipient: Recipient) : BaseDialog() { class DownloadDialog(private val recipient: Recipient) : DialogFragment() {
@Inject lateinit var contactDB: SessionContactDatabase @Inject lateinit var contactDB: SessionContactDatabase
override fun setContentView(builder: AlertDialog.Builder) { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = sessionDialog {
val binding = DialogDownloadBinding.inflate(LayoutInflater.from(requireContext()))
val sessionID = recipient.address.toString() val sessionID = recipient.address.toString()
val contact = contactDB.getContactWithSessionID(sessionID) val contact = contactDB.getContactWithSessionID(sessionID)
val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID
val title = resources.getString(R.string.dialog_download_title, name) title(resources.getString(R.string.dialog_download_title, name))
binding.downloadTitleTextView.text = title
val explanation = resources.getString(R.string.dialog_download_explanation, name) val explanation = resources.getString(R.string.dialog_download_explanation, name)
val spannable = SpannableStringBuilder(explanation) val spannable = SpannableStringBuilder(explanation)
val startIndex = explanation.indexOf(name) val startIndex = explanation.indexOf(name)
spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
binding.downloadExplanationTextView.text = spannable text(spannable)
binding.cancelButton.setOnClickListener { dismiss() }
binding.downloadButton.setOnClickListener { trust() } button(R.string.dialog_download_button_title, R.string.AccessibilityId_download_media) { trust() }
builder.setView(binding.root) cancelButton { dismiss() }
} }
private fun trust() { private fun trust() {
@ -50,4 +49,4 @@ class DownloadDialog(private val recipient: Recipient) : BaseDialog() {
JobQueue.shared.resumePendingJobs(AttachmentDownloadJob.KEY) JobQueue.shared.resumePendingJobs(AttachmentDownloadJob.KEY)
dismiss() dismiss()
} }
} }

View File

@ -1,45 +1,41 @@
package org.thoughtcrime.securesms.conversation.v2.dialogs package org.thoughtcrime.securesms.conversation.v2.dialogs
import android.app.Dialog
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Bundle
import android.text.Spannable import android.text.Spannable
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.style.StyleSpan import android.text.style.StyleSpan
import android.view.LayoutInflater
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AppCompatActivity
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.databinding.DialogJoinOpenGroupBinding
import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.utilities.OpenGroupUrlParser import org.session.libsession.utilities.OpenGroupUrlParser
import org.session.libsignal.utilities.ThreadUtils import org.session.libsignal.utilities.ThreadUtils
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
import org.thoughtcrime.securesms.groups.OpenGroupManager import org.thoughtcrime.securesms.groups.OpenGroupManager
import org.thoughtcrime.securesms.sessionDialog
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
/** Shown upon tapping an open group invitation. */ /** Shown upon tapping an open group invitation. */
class JoinOpenGroupDialog(private val name: String, private val url: String) : BaseDialog() { class JoinOpenGroupDialog(private val name: String, private val url: String) : DialogFragment() {
override fun setContentView(builder: AlertDialog.Builder) { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = sessionDialog {
val binding = DialogJoinOpenGroupBinding.inflate(LayoutInflater.from(requireContext())) title(resources.getString(R.string.dialog_join_open_group_title, name))
val title = resources.getString(R.string.dialog_join_open_group_title, name)
binding.joinOpenGroupTitleTextView.text = title
val explanation = resources.getString(R.string.dialog_join_open_group_explanation, name) val explanation = resources.getString(R.string.dialog_join_open_group_explanation, name)
val spannable = SpannableStringBuilder(explanation) val spannable = SpannableStringBuilder(explanation)
val startIndex = explanation.indexOf(name) val startIndex = explanation.indexOf(name)
spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) spannable.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + name.count(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
binding.joinOpenGroupExplanationTextView.text = spannable text(spannable)
binding.cancelButton.setOnClickListener { dismiss() } cancelButton { dismiss() }
binding.joinButton.setOnClickListener { join() } button(R.string.open_group_invitation_view__join_accessibility_description) { join() }
builder.setView(binding.root)
} }
private fun join() { private fun join() {
val openGroup = OpenGroupUrlParser.parseUrl(url) val openGroup = OpenGroupUrlParser.parseUrl(url)
val activity = requireContext() as AppCompatActivity val activity = requireActivity()
ThreadUtils.queue { ThreadUtils.queue {
try { try {
OpenGroupManager.add(openGroup.server, openGroup.room, openGroup.serverPublicKey, activity) openGroup.apply { OpenGroupManager.add(server, room, serverPublicKey, activity) }
MessagingModuleConfiguration.shared.storage.onOpenGroupAdded(openGroup.server) MessagingModuleConfiguration.shared.storage.onOpenGroupAdded(openGroup.server)
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(activity) ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(activity)
} catch (e: Exception) { } catch (e: Exception) {
@ -48,4 +44,4 @@ class JoinOpenGroupDialog(private val name: String, private val url: String) : B
} }
dismiss() dismiss()
} }
} }

View File

@ -1,20 +1,21 @@
package org.thoughtcrime.securesms.conversation.v2.dialogs package org.thoughtcrime.securesms.conversation.v2.dialogs
import android.view.LayoutInflater import android.app.Dialog
import androidx.appcompat.app.AlertDialog import android.os.Bundle
import network.loki.messenger.databinding.DialogLinkPreviewBinding import androidx.fragment.app.DialogFragment
import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog import org.thoughtcrime.securesms.sessionDialog
/** Shown the first time the user inputs a URL that could generate a link preview, to /** Shown the first time the user inputs a URL that could generate a link preview, to
* let them know that Session offers the ability to send and receive link previews. */ * let them know that Session offers the ability to send and receive link previews. */
class LinkPreviewDialog(private val onEnabled: () -> Unit) : BaseDialog() { class LinkPreviewDialog(private val onEnabled: () -> Unit) : DialogFragment() {
override fun setContentView(builder: AlertDialog.Builder) { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = sessionDialog {
val binding = DialogLinkPreviewBinding.inflate(LayoutInflater.from(requireContext())) title(R.string.dialog_link_preview_title)
binding.cancelButton.setOnClickListener { dismiss() } text(R.string.dialog_link_preview_explanation)
binding.enableLinkPreviewsButton.setOnClickListener { enable() } button(R.string.dialog_link_preview_enable_button_title) { enable() }
builder.setView(binding.root) cancelButton { dismiss() }
} }
private fun enable() { private fun enable() {
@ -22,4 +23,4 @@ class LinkPreviewDialog(private val onEnabled: () -> Unit) : BaseDialog() {
dismiss() dismiss()
onEnabled() onEnabled()
} }
} }

View File

@ -1,22 +1,23 @@
package org.thoughtcrime.securesms.conversation.v2.dialogs package org.thoughtcrime.securesms.conversation.v2.dialogs
import android.view.LayoutInflater import android.app.Dialog
import androidx.appcompat.app.AlertDialog import android.os.Bundle
import network.loki.messenger.databinding.DialogSendSeedBinding import androidx.fragment.app.DialogFragment
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog import network.loki.messenger.R
import org.thoughtcrime.securesms.sessionDialog
/** Shown if the user is about to send their recovery phrase to someone. */ /** Shown if the user is about to send their recovery phrase to someone. */
class SendSeedDialog(private val proceed: (() -> Unit)? = null) : BaseDialog() { class SendSeedDialog(private val proceed: (() -> Unit)? = null) : DialogFragment() {
override fun setContentView(builder: AlertDialog.Builder) { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = sessionDialog {
val binding = DialogSendSeedBinding.inflate(LayoutInflater.from(requireContext())) title(R.string.dialog_send_seed_title)
binding.cancelButton.setOnClickListener { dismiss() } text(R.string.dialog_send_seed_explanation)
binding.sendSeedButton.setOnClickListener { send() } button(R.string.dialog_send_seed_send_button_title) { send() }
builder.setView(binding.root) cancelButton()
} }
private fun send() { private fun send() {
proceed?.invoke() proceed?.invoke()
dismiss() dismiss()
} }
} }

View File

@ -1,26 +0,0 @@
package org.thoughtcrime.securesms.conversation.v2.utilities
import android.app.Dialog
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import org.thoughtcrime.securesms.util.UiModeUtilities
open class BaseDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(requireContext())
setContentView(builder)
val result = builder.create()
result.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val isLightMode = UiModeUtilities.isDayUiMode(requireContext())
result.window?.setDimAmount(if (isLightMode) 0.1f else 0.75f)
return result
}
open fun setContentView(builder: AlertDialog.Builder) {
// To be overridden by subclasses
}
}

View File

@ -1,9 +1,12 @@
package org.thoughtcrime.securesms.preferences package org.thoughtcrime.securesms.preferences
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.appcompat.app.AlertDialog import android.view.View
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.DividerItemDecoration
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -15,10 +18,10 @@ import network.loki.messenger.databinding.DialogClearAllDataBinding
import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeAPI
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog import org.thoughtcrime.securesms.sessionDialog
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
class ClearAllDataDialog : BaseDialog() { class ClearAllDataDialog : DialogFragment() {
private lateinit var binding: DialogClearAllDataBinding private lateinit var binding: DialogClearAllDataBinding
enum class Steps { enum class Steps {
@ -35,7 +38,11 @@ class ClearAllDataDialog : BaseDialog() {
updateUI() updateUI()
} }
override fun setContentView(builder: AlertDialog.Builder) { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = sessionDialog {
view(createView())
}
private fun createView(): View {
binding = DialogClearAllDataBinding.inflate(LayoutInflater.from(requireContext())) binding = DialogClearAllDataBinding.inflate(LayoutInflater.from(requireContext()))
val device = RadioOption("deviceOnly", requireContext().getString(R.string.dialog_clear_all_data_clear_device_only)) val device = RadioOption("deviceOnly", requireContext().getString(R.string.dialog_clear_all_data_clear_device_only))
val network = RadioOption("deviceAndNetwork", requireContext().getString(R.string.dialog_clear_all_data_clear_device_and_network)) val network = RadioOption("deviceAndNetwork", requireContext().getString(R.string.dialog_clear_all_data_clear_device_and_network))
@ -62,8 +69,7 @@ class ClearAllDataDialog : BaseDialog() {
Steps.DELETING -> { /* do nothing intentionally */ } Steps.DELETING -> { /* do nothing intentionally */ }
} }
} }
builder.setView(binding.root) return binding.root
builder.setCancelable(false)
} }
private fun updateUI() { private fun updateUI() {

View File

@ -1,38 +1,34 @@
package org.thoughtcrime.securesms.preferences package org.thoughtcrime.securesms.preferences
import android.app.Dialog
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.view.LayoutInflater import android.os.Bundle
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.databinding.DialogSeedBinding
import org.session.libsignal.crypto.MnemonicCodec import org.session.libsignal.crypto.MnemonicCodec
import org.session.libsignal.utilities.hexEncodedPrivateKey import org.session.libsignal.utilities.hexEncodedPrivateKey
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.crypto.MnemonicUtilities import org.thoughtcrime.securesms.crypto.MnemonicUtilities
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog import org.thoughtcrime.securesms.sessionDialog
class SeedDialog : BaseDialog() {
class SeedDialog: DialogFragment() {
private val seed by lazy { private val seed by lazy {
var hexEncodedSeed = IdentityKeyUtil.retrieve(requireContext(), IdentityKeyUtil.LOKI_SEED) val hexEncodedSeed = IdentityKeyUtil.retrieve(requireContext(), IdentityKeyUtil.LOKI_SEED)
if (hexEncodedSeed == null) { ?: IdentityKeyUtil.getIdentityKeyPair(requireContext()).hexEncodedPrivateKey // Legacy account
hexEncodedSeed = IdentityKeyUtil.getIdentityKeyPair(requireContext()).hexEncodedPrivateKey // Legacy account
} MnemonicCodec { fileName -> MnemonicUtilities.loadFileContents(requireContext(), fileName) }
val loadFileContents: (String) -> String = { fileName -> .encode(hexEncodedSeed, MnemonicCodec.Language.Configuration.english)
MnemonicUtilities.loadFileContents(requireContext(), fileName)
}
MnemonicCodec(loadFileContents).encode(hexEncodedSeed!!, MnemonicCodec.Language.Configuration.english)
} }
override fun setContentView(builder: AlertDialog.Builder) { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = sessionDialog {
val binding = DialogSeedBinding.inflate(LayoutInflater.from(requireContext())) title(R.string.dialog_seed_title)
binding.seedTextView.text = seed text(R.string.dialog_seed_explanation)
binding.closeButton.setOnClickListener { dismiss() } text(seed, R.style.SessionIDTextView)
binding.copyButton.setOnClickListener { copySeed() } button(R.string.copy, R.string.AccessibilityId_copy_recovery_phrase) { copySeed() }
builder.setView(binding.root) button(R.string.close) { dismiss() }
} }
private fun copySeed() { private fun copySeed() {
@ -42,4 +38,4 @@ class SeedDialog : BaseDialog() {
Toast.makeText(requireContext(), R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show()
dismiss() dismiss()
} }
} }

View File

@ -1,17 +1,18 @@
package org.thoughtcrime.securesms.preferences package org.thoughtcrime.securesms.preferences
import android.app.Dialog
import android.content.ContentResolver import android.content.ContentResolver
import android.content.ContentValues import android.content.ContentValues
import android.content.Intent import android.content.Intent
import android.media.MediaScannerConnection import android.media.MediaScannerConnection
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.provider.MediaStore import android.provider.MediaStore
import android.view.LayoutInflater
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
@ -20,11 +21,10 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import network.loki.messenger.BuildConfig import network.loki.messenger.BuildConfig
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.databinding.DialogShareLogsBinding
import org.session.libsignal.utilities.ExternalStorageUtil import org.session.libsignal.utilities.ExternalStorageUtil
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog import org.thoughtcrime.securesms.sessionDialog
import org.thoughtcrime.securesms.util.FileProviderUtil import org.thoughtcrime.securesms.util.FileProviderUtil
import org.thoughtcrime.securesms.util.StreamUtil import org.thoughtcrime.securesms.util.StreamUtil
import java.io.File import java.io.File
@ -33,21 +33,15 @@ import java.io.IOException
import java.util.Objects import java.util.Objects
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class ShareLogsDialog : BaseDialog() { class ShareLogsDialog : DialogFragment() {
private var shareJob: Job? = null private var shareJob: Job? = null
override fun setContentView(builder: AlertDialog.Builder) { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = sessionDialog {
val binding = DialogShareLogsBinding.inflate(LayoutInflater.from(requireContext())) title(R.string.dialog_share_logs_title)
binding.cancelButton.setOnClickListener { text(R.string.dialog_share_logs_explanation)
dismiss() button(R.string.share) { shareLogs() }
} cancelButton { dismiss() }
binding.shareButton.setOnClickListener {
// start the export and share
shareLogs()
}
builder.setView(binding.root)
builder.setCancelable(false)
} }
private fun shareLogs() { private fun shareLogs() {

View File

@ -7,10 +7,10 @@ import android.view.View
import androidx.annotation.StyleRes import androidx.annotation.StyleRes
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.DialogFragment
import network.loki.messenger.R import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.BaseActionBarActivity import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog
fun BaseActionBarActivity.setUpActionBarSessionLogo(hideBackButton: Boolean = false) { fun BaseActionBarActivity.setUpActionBarSessionLogo(hideBackButton: Boolean = false) {
val actionbar = supportActionBar!! val actionbar = supportActionBar!!
@ -66,7 +66,7 @@ interface ActivityDispatcher {
fun get(context: Context) = context.getSystemService(SERVICE) as? ActivityDispatcher fun get(context: Context) = context.getSystemService(SERVICE) as? ActivityDispatcher
} }
fun dispatchIntent(body: (Context)->Intent?) fun dispatchIntent(body: (Context)->Intent?)
fun showDialog(baseDialog: BaseDialog, tag: String? = null) fun showDialog(dialogFragment: DialogFragment, tag: String? = null)
} }
fun TextSecurePreferences.themeState(): ThemeState { fun TextSecurePreferences.themeState(): ThemeState {

View File

@ -1,57 +0,0 @@
<?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:gravity="center_horizontal"
android:orientation="vertical"
android:elevation="4dp"
android:padding="@dimen/medium_spacing">
<TextView
android:id="@+id/blockedTitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_blocked_title"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
android:textSize="@dimen/large_font_size" />
<TextView
android:id="@+id/blockedExplanationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:text="@string/dialog_blocked_explanation"
android:paddingHorizontal="@dimen/medium_spacing"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/small_font_size"
android:textAlignment="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:orientation="horizontal">
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/cancelButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:text="@string/cancel" />
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/unblockButton"
android:contentDescription="@string/AccessibilityId_block_confirm"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:layout_marginStart="@dimen/medium_spacing"
android:text="@string/ConversationActivity_unblock" />
</LinearLayout>
</LinearLayout>

View File

@ -1,58 +0,0 @@
<?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:gravity="center_horizontal"
android:orientation="vertical"
android:elevation="4dp"
android:padding="@dimen/medium_spacing">
<TextView
android:id="@+id/downloadTitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_download_title"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
android:textSize="@dimen/large_font_size" />
<TextView
android:id="@+id/downloadExplanationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:text="@string/dialog_download_explanation"
android:paddingHorizontal="@dimen/medium_spacing"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/small_font_size"
android:textAlignment="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:orientation="horizontal">
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/cancelButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:contentDescription="@string/AccessibilityId_dont_download_media"
android:text="@string/cancel" />
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/downloadButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:layout_marginStart="@dimen/medium_spacing"
android:contentDescription="@string/AccessibilityId_download_media"
android:text="@string/dialog_download_button_title" />
</LinearLayout>
</LinearLayout>

View File

@ -1,56 +0,0 @@
<?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:gravity="center_horizontal"
android:orientation="vertical"
android:elevation="4dp"
android:padding="@dimen/medium_spacing">
<TextView
android:id="@+id/joinOpenGroupTitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_join_open_group_title"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
android:textSize="@dimen/large_font_size" />
<TextView
android:id="@+id/joinOpenGroupExplanationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:text="@string/dialog_join_open_group_explanation"
android:paddingHorizontal="@dimen/medium_spacing"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/small_font_size"
android:textAlignment="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:orientation="horizontal">
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/cancelButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:text="@string/cancel" />
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/joinButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:layout_marginStart="@dimen/medium_spacing"
android:text="@string/open_group_invitation_view__join_accessibility_description" />
</LinearLayout>
</LinearLayout>

View File

@ -1,60 +0,0 @@
<?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:gravity="center_horizontal"
android:orientation="vertical"
android:elevation="4dp"
android:padding="@dimen/medium_spacing">
<TextView
android:id="@+id/linkPreviewDialogTitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_link_preview_title"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
android:textSize="@dimen/large_font_size" />
<TextView
android:id="@+id/linkPreviewDialogExplanationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:text="@string/dialog_link_preview_explanation"
android:paddingHorizontal="@dimen/medium_spacing"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/small_font_size"
android:textAlignment="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:orientation="horizontal">
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/cancelButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:text="@string/cancel"
android:contentDescription="@string/AccessibilityId_cancel_link_preview_button"/>
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/enableLinkPreviewsButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:layout_marginStart="@dimen/medium_spacing"
android:text="@string/dialog_link_preview_enable_button_title"
android:contentDescription="@string/AccessibilityId_enable_link_preview_button"
/>
</LinearLayout>
</LinearLayout>

View File

@ -1,56 +0,0 @@
<?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:gravity="center_horizontal"
android:orientation="vertical"
android:elevation="4dp"
android:padding="@dimen/medium_spacing">
<TextView
android:id="@+id/openURLTitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_open_url_title"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
android:textSize="@dimen/large_font_size" />
<TextView
android:id="@+id/openURLExplanationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:text="@string/dialog_open_url_explanation"
android:paddingHorizontal="@dimen/medium_spacing"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/small_font_size"
android:textAlignment="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:orientation="horizontal">
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/cancelButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:text="@string/cancel" />
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/openURLButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:layout_marginStart="@dimen/medium_spacing"
android:text="@string/open" />
</LinearLayout>
</LinearLayout>

View File

@ -1,69 +0,0 @@
<?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:tools="http://schemas.android.com/tools"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="@dimen/medium_spacing">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_seed_title"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
android:textAlignment="center"
android:textSize="@dimen/medium_font_size" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:text="@string/dialog_seed_explanation"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/medium_font_size"
android:textAlignment="center"
android:alpha="0.6" />
<TextView
style="@style/SessionIDTextView"
android:contentDescription="@string/AccessibilityId_recovery_phrase"
android:id="@+id/seedTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:padding="@dimen/small_spacing"
tools:text="habitat kiwi amply iceberg dog nerves spiderman soft match partial awakened maximum degrees"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/small_font_size"
android:textAlignment="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:orientation="horizontal">
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:contentDescription="@string/AccessibilityId_cancel_button"
android:id="@+id/copyButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:layout_marginStart="@dimen/medium_spacing"
android:text="@string/copy" />
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:contentDescription="@string/AccessibilityId_copy_recovery_phrase"
android:id="@+id/closeButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:text="@string/close" />
</LinearLayout>
</LinearLayout>

View File

@ -1,63 +0,0 @@
<?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:gravity="center_horizontal"
android:orientation="vertical"
android:elevation="4dp"
android:padding="@dimen/medium_spacing">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_share_logs_title"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
android:textSize="@dimen/medium_font_size" />
<TextView
android:id="@+id/dialogDescriptionText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:text="@string/dialog_share_logs_explanation"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/small_font_size"
android:textAlignment="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_spacing"
android:orientation="horizontal">
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/cancelButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:text="@string/cancel" />
<Button
style="@style/Widget.Session.Button.Dialog.UnimportantText"
android:id="@+id/shareButton"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
android:layout_marginStart="@dimen/medium_spacing"
android:text="@string/share" />
<com.github.ybq.android.spinkit.SpinKitView
style="@style/SpinKitView.Small.ThreeBounce"
android:id="@+id/progressBar"
android:layout_width="0dp"
android:layout_height="@dimen/small_button_height"
android:layout_weight="1"
app:SpinKit_Color="?colorAccent"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>