145 lines
4.5 KiB
Kotlin
Raw Normal View History

2023-05-29 18:02:20 +09:30
package org.thoughtcrime.securesms
import android.content.Context
import android.view.View
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.Button
import android.widget.LinearLayout
import android.widget.LinearLayout.VERTICAL
import android.widget.TextView
2023-05-30 16:49:07 +09:30
import androidx.annotation.AttrRes
import androidx.annotation.LayoutRes
2023-05-29 18:02:20 +09:30
import androidx.annotation.StringRes
import androidx.annotation.StyleRes
import androidx.appcompat.app.AlertDialog
import androidx.core.view.setMargins
2023-05-30 16:49:07 +09:30
import androidx.core.view.setPadding
2023-05-29 18:02:20 +09:30
import androidx.core.view.updateMargins
import network.loki.messenger.R
import org.thoughtcrime.securesms.util.toPx
2023-05-30 16:49:07 +09:30
import java.lang.ref.Reference
2023-05-29 18:02:20 +09:30
2023-05-30 16:49:07 +09:30
@DslMarker
@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
annotation class DialogDsl
@DialogDsl
2023-05-29 18:02:20 +09:30
class SessionDialogBuilder(val context: Context) {
2023-05-30 16:49:07 +09:30
private val dialogBuilder: AlertDialog.Builder = AlertDialog.Builder(context)
private var dialog: AlertDialog? = null
private fun dismiss() = dialog?.dismiss()
private val topView = LinearLayout(context).apply { orientation = VERTICAL }
.also(dialogBuilder::setCustomTitle)
2023-05-29 18:02:20 +09:30
private val root = LinearLayout(context).apply { orientation = VERTICAL }
2023-05-30 16:49:07 +09:30
.also(dialogBuilder::setView)
fun title(@StringRes id: Int) = title(context.getString(id))
fun title(text: CharSequence?) = title(text?.toString())
fun title(text: String?) {
text(text, R.style.TextAppearance_AppCompat_Title) { setPadding(toPx(20, resources)) }
2023-05-29 18:02:20 +09:30
}
2023-05-30 16:49:07 +09:30
fun text(@StringRes id: Int, style: Int = 0) = text(context.getString(id), style)
fun text(text: CharSequence?) = text(text?.toString())
fun text(text: String?, @StyleRes style: Int = 0) {
text(text, style) {
layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
2023-05-29 18:02:20 +09:30
.apply { toPx(40, resources).let { updateMargins(it, 0, it, 0) } }
2023-05-30 16:49:07 +09:30
}
}
private fun text(text: String?, @StyleRes style: Int, modify: TextView.() -> Unit) {
text ?: return
TextView(context, null, 0, style)
.apply {
setText(text)
textAlignment = View.TEXT_ALIGNMENT_CENTER
modify()
}.let(topView::addView)
2023-05-29 18:02:20 +09:30
}
2023-05-30 16:49:07 +09:30
fun view(view: View) {
dialogBuilder.setView(view)
2023-05-29 18:02:20 +09:30
}
2023-05-30 16:49:07 +09:30
fun view(@LayoutRes layout: Int) {
dialogBuilder.setView(layout)
}
fun setIconAttribute(@AttrRes icon: Int) {
dialogBuilder.setIconAttribute(icon)
}
fun singleChoiceItems(
options: Array<String>,
currentSelected: Int,
onSelect: (Int) -> Unit
) {
dialogBuilder.setSingleChoiceItems(
options,
currentSelected
) { dialog, it -> onSelect(it); dialog.dismiss() }
}
fun buttons(build: (@DialogDsl ButtonsBuilder).() -> Unit) {
ButtonsBuilder(context, ::dismiss).build(build).let(root::addView)
}
fun show(): AlertDialog = dialogBuilder.show()
2023-05-29 18:02:20 +09:30
}
2023-05-30 16:49:07 +09:30
@DialogDsl
class ButtonsBuilder(val context: Context, val dismiss: () -> Unit) {
2023-05-29 18:02:20 +09:30
val root = LinearLayout(context)
2023-05-30 16:49:07 +09:30
fun destructiveButton(
@StringRes text: Int,
@StringRes contentDescription: Int,
listener: () -> Unit = {}
) {
button(
text,
contentDescription,
R.style.Widget_Session_Button_Dialog_DestructiveText,
listener
)
2023-05-29 18:02:20 +09:30
}
2023-05-30 16:49:07 +09:30
fun cancelButton(listener: (() -> Unit) = {}) = button(android.R.string.cancel, R.string.AccessibilityId_cancel_button, listener = listener)
2023-05-29 18:02:20 +09:30
fun button(
@StringRes text: Int,
@StringRes contentDescriptionRes: Int = 0,
@StyleRes style: Int = R.style.Widget_Session_Button_Dialog_UnimportantText,
2023-05-30 16:49:07 +09:30
listener: (() -> Unit) = {}
) {
2023-05-29 18:02:20 +09:30
Button(context, null, 0, style)
.apply {
2023-05-30 16:49:07 +09:30
setText(text)
contentDescription = resources.getString(contentDescriptionRes)
2023-05-29 18:02:20 +09:30
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1f)
.apply { setMargins(toPx(20, resources)) }
2023-05-30 16:49:07 +09:30
setOnClickListener {
listener.invoke()
dismiss()
}
2023-05-29 18:02:20 +09:30
}
.let(root::addView)
}
internal fun build(build: ButtonsBuilder.() -> Unit): LinearLayout {
build()
return root
}
}
fun Context.sessionDialog(build: SessionDialogBuilder.() -> Unit): AlertDialog =
SessionDialogBuilder(this).apply { build() }.show()