Repository: corona-warn-app/cwa-app-android
File: Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/dialog/DialogFragmentTemplate.kt (Kotlin)

Code before:
        val config = requireArguments().getParcelable<Config>(PARAM_DIALOG_CONFIG)
        requireNotNull(config) { "DialogFragment config is null" }
        isCancelable = config.isCancelable

        return config.run {
            MaterialAlertDialogBuilder(requireContext())
                .setTitle(titleRes)
                .setMessage(messageRes)
                .setPositiveButton(positiveButtonRes) { _, _ -> setAction(Action.PositiveButtonClicked) }
                .setNegativeButton(negativeButtonRes) { _, _ -> setAction(Action.NegativeButtonClicked) }
                .setNeutralButton(neutralButtonRes) { _, _ -> setAction(Action.NeutralButtonClicked) }
                .create()
        }
    }

    override fun onStart() {
        super.onStart()
        val config = requireArguments().getParcelable<Config>(PARAM_DIALOG_CONFIG)
        if (config?.isDeleteDialog == true) {
            (dialog as AlertDialog).getButton(DialogInterface.BUTTON_POSITIVE)
                ?.setTextColor(requireContext().getColorCompat(R.color.colorTextDeleteButtonDialog))
        }
    }

    private fun setAction(action: Action) {
        Timber.d("DialogFragment setAction(action=%s", action)
        setFragmentResult(REQUEST_KEY, bundleOf(PARAM_DIALOG_ACTION to action))
    }

    override fun onDismiss(dialog: DialogInterface) {
        Timber.d("DialogFragment dismissed")
        setAction(Action.Dismissed)
        super.onDismiss(dialog)
    }

    enum class Action {
        PositiveButtonClicked,
        NegativeButtonClicked,
        NeutralButtonClicked,
        Dismissed
    }

    @Parcelize
    data class Config(
        val titleRes: String,
        val messageRes: String,
        val positiveButtonRes: String,
        val negativeButtonRes: String?,
        val neutralButtonRes: String?,
        val isDeleteDialog: Boolean = false,
        val isCancelable: Boolean = true

Review comment (suggestion):
This seems to be used to set the color of the positive button to red. I would prefer a more obvious and direct way, eg. color of positive button, so I can use orange or color a dialog button although it is not for deletion.

Code after:
        val dialogParams = requireArguments().getParcelable<DialogTemplateParams>(DIALOG_TEMPLATE_PARAMS)
        requireNotNull(dialogParams) { "DialogTemplateParams is null" }
        isCancelable = dialogParams.cancelable == true
        return dialogParams.materialDialog?.apply(dialogParams.config)?.create()
            ?: MaterialAlertDialogBuilder(requireContext()).apply(dialogParams.config).create()
    }

    override fun onStart() {
        super.onStart()
        val dialogParams = requireArguments().getParcelable<DialogTemplateParams>(DIALOG_TEMPLATE_PARAMS)
        if (dialogParams?.isDeleteDialog == true) {
            (dialog as AlertDialog).getButton(DialogInterface.BUTTON_POSITIVE)
                ?.setTextColor(requireContext().getColorCompat(R.color.colorTextDeleteButtonDialog))
        }
    }

    override fun onDismiss(dialog: DialogInterface) {
        val dialogParams = requireArguments().getParcelable<DialogTemplateParams>(DIALOG_TEMPLATE_PARAMS)
        dialogParams?.dismissAction?.let { it() }
        super.onDismiss(dialog)
    }

    @Parcelize
    data class DialogTemplateParams(
        val cancelable: Boolean = true,
        val isDeleteDialog: Boolean = false,
        val dismissAction: () -> Unit = { },
        val materialDialog: @RawValue MaterialAlertDialogBuilder? = null,
        val config: MaterialAlertDialogBuilder.() -> Unit
    ) : Parcelable

    companion object {
        val TAG: String = DialogFragmentTemplate::class.java.simpleName
        private val DIALOG_TEMPLATE_PARAMS = "${DialogFragmentTemplate.TAG}_DIALOG_TEMPLATE_PARAMS"

        fun newInstance(dialogParams: DialogTemplateParams) = DialogFragmentTemplate().apply {
            arguments = bundleOf(DIALOG_TEMPLATE_PARAMS to dialogParams)
        }
    }
}