Untitled

mail@pastecode.io avatar
unknown
plain_text
23 days ago
13 kB
4
Indexable
Never
class AppDialog : DialogFragment(), DialogDelegate, CoroutineScope {

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main
    private val icon: Int? by lazy { arguments?.getInt(ARG_ICON) }
    private val title: String? by lazy { arguments?.getString(ARG_TITLE) }
    private val message: String? by lazy { arguments?.getString(ARG_MESSAGE) }
    private val htmlMessage: String? by lazy { arguments?.getString(ARG_HTML_MESSAGE) }
    private val error: String? by lazy { arguments?.getString(ARG_ERROR) }
    private val positiveButtonText: String? by lazy { arguments?.getString(ARG_POSITIVE_BUTTON_TEXT) }
    private val negativeButtonText: String? by lazy { arguments?.getString(ARG_NEGATIVE_BUTTON_TEXT) }
    private val fallbackButtonText: String? by lazy { arguments?.getString(ARG_FALLBACK_BUTTON_TEXT) }
    private val instructionMessage: String? by lazy { arguments?.getString(ARG_INSTRUCTION_MESSAGE) }


    private val isDismissedOnTapAnywhere: Boolean? by lazy {
        arguments?.getBoolean(ARG_IS_DISMISSED_ON_TAP_ANYWHERE, false)
    }
    private val autoDismissTime: Long? by lazy {
        arguments?.getLong(ARG_AUTO_DISMISS_TIME)?.takeIf { it > 0 }
    }
    private var positiveButtonAction: ((DialogDelegate) -> Unit)? = null
    private var negativeButtonAction: ((DialogDelegate) -> Unit)? = null
    private var fallbackButtonAction: ((DialogDelegate) -> Unit)? = null

    private var volumeUpAction: (() -> Unit)? = null
    private var volumeDownAction: (() -> Unit)? = null
    private var powerButtonAction: (() -> Unit)? = null
    private var isPaused: Boolean = false
    private val screenOffReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent?.action == Intent.ACTION_SCREEN_OFF) {
                powerButtonAction?.invoke()
                Log.d(TAG, "Screen Off received")
                dismissAllDialogs(parentFragmentManager)
            }
        }
    }

    private var onDismissListener: (() -> Unit)? = null
    private var dismissDialogJob: Job? = null

    private var _binding: CommonDialogDefaultBinding? = null
    private val binding get() = _binding!!

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(STYLE_NO_TITLE, R.style.AppTheme_Dialog)
        Log.d(TAG, "onCreate called")
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
//        dialog?.window?.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
        Log.d(TAG, "onCreateView called")
        _binding = CommonDialogDefaultBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        with(binding) {
            icon?.run {
                Log.d("AppDialog", "icon: $this")
                iconImageView.setImageResource(this)
                if (this == 0) {
                    iconImageView.isGone = true
                }
            } ?: run { iconImageView.isGone = true }
            title?.run(titleTextView::setText) ?: run {
                titleTextView.isGone = true
            }
            message?.run(messageTextView::setText) ?: run {
                messageTextView.isGone = true
            }
            instructionMessage?.run(instructionTextView::setText) ?: run {
                instructionLayout.isGone = true
            }
            htmlMessage?.run {
                messageHTMLTextView.text = Html.fromHtml(this)
            } ?: run {
                messageHTMLTextView.isGone = true
            }
            error?.run(errorTextView::setText) ?: run {
                errorTextView.isGone = true
            }
            positiveButtonText?.run {
                positiveButton.text = this
                positiveButton.setOnClickListener {
                    positiveButtonAction?.invoke(this@AppDialog)
                }
            } ?: run {
                positiveButton.isVisible = false
            }
            fallbackButtonText?.run {
                fallbackButton.text = this
                fallbackButton.setOnClickListener {
                    fallbackButtonAction?.invoke(this@AppDialog)
                    return@setOnClickListener
                }
            } ?: run {
                fallbackButton.isVisible = false
            }
            negativeButtonText?.run {
                negativeButton.text = this
                negativeButton.setOnClickListener {
                    negativeButtonAction?.invoke(this@AppDialog)
                }
            } ?: run {
                negativeButton.isVisible = false
            }
            isDismissedOnTapAnywhere?.let {
                if (it) {
                    isCancelable = true
                    view.setOnClickListener {
                        dismiss()
                    }
                }
            }
        }
        dialog?.setOnKeyListener { _, keyCode, event ->
            if (
                (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_VOLUME_UP)
            ) {
                volumeUpAction?.invoke()
                return@setOnKeyListener true
            } else if (
                (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
            ) {
                volumeDownAction?.invoke()
                return@setOnKeyListener true
            } else if (
                event.action == KeyEvent.ACTION_DOWN && KeyEvent.KEYCODE_POWER == event.keyCode
            ) {
                Log.d(TAG, "Power button pressed")
                powerButtonAction?.invoke()
                return@setOnKeyListener true
            }
            false
        }
    }

//    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
//        val keyPressed = event.keyCode
//        return if (keyPressed == KeyEvent.KEYCODE_POWER) {
//            Log.d("###", "Power button long click")
//            Toast.makeText(this, "Clicked: $keyPressed", Toast.LENGTH_SHORT).show()
//            true
//        } else {
//            super.dispatchKeyEvent(event)
//        }
//    }

    override fun onResume() {
        super.onResume()
        autoDismissTime?.let {
            dismissDialogJob = launch {
                delay(it)
                this@AppDialog.dismiss()
            }
        }
        val filter = IntentFilter(Intent.ACTION_SCREEN_OFF)
        requireContext().registerReceiver(screenOffReceiver, filter)
        Log.d(TAG, "onResume Called")
    }

    override fun onPause() {
        super.onPause()
        onDismissListener?.invoke()
        dismissDialogJob?.cancel()
        requireContext().unregisterReceiver(screenOffReceiver)
//        if (dialog != null) {
//            Log.d(TAG, "Screen Off received")
//            dismissAllDialogs(parentFragmentManager)
//            dialog?.dismiss()
//        }
        Log.d(TAG, "onPause Called")
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        onDismissListener?.invoke()
        dismissDialogJob?.cancel()
//        powerButtonAction?.invoke()
        Log.d(TAG, "onDismiss Called")
    }

    override fun onDestroyView() {
        super.onDestroyView()
        Log.d(TAG, "onDestroyView Called")
        _binding = null
    }

    companion object {
        private const val ARG_ICON = "ARG_ICON"
        private const val ARG_MESSAGE = "ARG_MESSAGE"
        private const val ARG_TITLE = "ARG_TITLE"
        private const val ARG_HTML_MESSAGE = "ARG_HTML_MESSAGE"
        private const val ARG_ERROR = "ARG_ERROR"
        private const val ARG_POSITIVE_BUTTON_TEXT = "ARG_POSITIVE_BUTTON_TEXT"
        private const val ARG_FALLBACK_BUTTON_TEXT = "ARG_FALLBACK_BUTTON_TEXT"
        private const val ARG_NEGATIVE_BUTTON_TEXT = "ARG_NEGATIVE_BUTTON_TEXT"
        private const val ARG_INSTRUCTION_MESSAGE = "ARG_INSTRUCTION_MESSAGE"
        private const val ARG_IS_DISMISSED_ON_TAP_ANYWHERE = "ARG_IS_DISMISSED_ON_TAP_ANYWHERE"
        private const val ARG_AUTO_DISMISS_TIME = "ARG_AUTO_DISMISS_TIME"
        private const val ARG_IS_GIF_ANIMATION = "ARG_IS_GIF_ANIMATION"
    }

    class Builder(private val context: Context) : BaseDialogBuilder(context) {
        private var icon: Int? = null
        private var title: String? = null
        private var error: String? = null
        private var onDismissListener: (() -> Unit)? = null
        private var autoDismissTime: Long? = null
        private var isCancelable: Boolean? = null
        private var isDismissedOnTapAnywhere: Boolean? = null
        private var htmlMessage: String? = null
        private var instructionMessage: String? = null
        private var volumeUpAction: (() -> Unit)? = null
        private var volumeDownAction: (() -> Unit)? = null
        private var powerButtonAction: (() -> Unit)? = null

        fun setIcon(@DrawableRes iconResId: Int) = apply {
            this.icon = iconResId
        }

        fun setHardwareButtonAction(buttonType: Int, action: () -> Unit) = apply {
            when (buttonType) {
                R.string.title_volume_up -> {
                    this.volumeUpAction = action
                }
                R.string.title_volume_down -> {
                    this.volumeDownAction = action
                }
                R.string.title_power_button -> {
                    this.powerButtonAction = action
                }
            }

        }

        fun setTitle(@StringRes titleResId: Int) = apply {
            this.title = context.getString(titleResId)
        }

        fun setTitle(title: String) = apply {
            this.title = title
        }

        fun setError(@StringRes errorResId: Int) = apply {
            this.error = context.getString(errorResId)
        }

        fun setError(error: String) = apply {
            this.error = error
        }

        fun setHTMLMessage(@StringRes htmlMessage: Int) = apply {
            this.htmlMessage = context.getString(htmlMessage)
        }

        fun setHTMLMessage(htmlMessage: String) = apply {
            this.htmlMessage = htmlMessage
        }

        fun setInstructionMessage(message: String) = apply {
            this.instructionMessage = message
        }

        fun setOnDismissListener(listener: () -> Unit) = apply {
            this.onDismissListener = listener
        }

        fun setAutoDismiss(timeMillis: Long) = apply {
            this.autoDismissTime = timeMillis
        }

        fun setCancelable(isCancelable: Boolean) = apply {
            this.isCancelable = isCancelable
        }

        fun setDismissedOnTapAnywhere(isDismissedOnTapAnywhere: Boolean) = apply {
            this.isDismissedOnTapAnywhere = isDismissedOnTapAnywhere
        }

        override fun build(): DialogFragment {
            val dialog = AppDialog()
            val arguments = Bundle().apply {
                icon?.let { putInt(ARG_ICON, it) }
                title?.let { putString(ARG_TITLE, it) }
                message?.let { putString(ARG_MESSAGE, it) }
                htmlMessage?.let { putString(ARG_HTML_MESSAGE, it) }
                error?.let { putString(ARG_ERROR, it) }
                positiveButtonText?.let { putString(ARG_POSITIVE_BUTTON_TEXT, it) }
                negativeButtonText?.let { putString(ARG_NEGATIVE_BUTTON_TEXT, it) }
                fallbackButtonText?.let { putString(ARG_FALLBACK_BUTTON_TEXT, it) }
                instructionMessage?.let { putString(ARG_INSTRUCTION_MESSAGE, it) }
                autoDismissTime?.let { putLong(ARG_AUTO_DISMISS_TIME, it) }
                isDismissedOnTapAnywhere?.let { putBoolean(ARG_IS_DISMISSED_ON_TAP_ANYWHERE, it) }
            }
            dialog.arguments = arguments
            positiveButtonAction?.let { dialog.positiveButtonAction = it }
            negativeButtonAction?.let { dialog.negativeButtonAction = it }
            fallbackButtonAction?.let { dialog.fallbackButtonAction = it }
            onDismissListener?.let { dialog.onDismissListener = it }
            isCancelable?.let { dialog.isCancelable = it }
            volumeUpAction?.let { dialog.volumeUpAction = it }
            volumeDownAction?.let { dialog.volumeDownAction = it }
            powerButtonAction?.let { dialog.powerButtonAction = it }
            return dialog
        }
    }
}
Leave a Comment