feat: 重构首页弹窗显示逻辑

This commit is contained in:
chenjuntao
2023-08-14 17:44:04 +08:00
parent eba7f31b32
commit d86dc7a03c
15 changed files with 1222 additions and 929 deletions

View File

@ -0,0 +1,127 @@
package com.gh.common.prioritychain
import android.app.Activity
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.FrameLayout
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.PopupAccelerateNotificationBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.fragment.MainWrapperViewModel
class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priority) {
private var mActivity: Activity? = null
private var mBaseHandler: BaseFragment.BaseHandler? = null
private var mGameList: List<GameEntity>? = null
private var mViewModel: MainWrapperViewModel? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(
activity: Activity,
baseHandler: BaseFragment.BaseHandler,
gameEntityList: List<GameEntity>?,
viewModel: MainWrapperViewModel
) {
mActivity = activity
mGameList = gameEntityList
mBaseHandler = baseHandler
mViewModel = viewModel
if (getStatus() == STATUS_PENDING) {
if (gameEntityList == null) {
processNext()
} else {
onProcess()
}
} else {
if (gameEntityList == null) {
updateStatus(STATUS_INVALID)
} else {
updateStatus(STATUS_VALID)
}
}
}
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
val accelerateSet =
HashSet(SPUtils.getStringSet(Constants.SP_ACCELERATE_NOTIFICATION_POP_UP_SET))
if (!mGameList.isNullOrEmpty() && !accelerateSet.contains(mGameList!![0].messageId)) {
showAccelerateNotificationPopupWindow(mGameList!![0]) {
processNext()
}
accelerateSet.add(mGameList!![0].messageId)
SPUtils.setStringSet(Constants.SP_ACCELERATE_NOTIFICATION_POP_UP_SET, accelerateSet)
} else {
processNext()
}
}
STATUS_INVALID -> {
processNext()
}
}
}
private fun showAccelerateNotificationPopupWindow(gameEntity: GameEntity?, dismissCallback: () -> Unit) {
val binding: PopupAccelerateNotificationBinding =
PopupAccelerateNotificationBinding.inflate(LayoutInflater.from(mActivity))
if (gameEntity != null) {
binding.gameIconView.displayGameIcon(gameEntity)
binding.gameNameTv.text = gameEntity.name
binding.root.setOnClickListener {
NewFlatLogUtils.logMessageInformClickPluginVersion(
gameEntity.id,
gameEntity.name!!
)
if (gameEntity.messageId.isNotEmpty()) {
// 把对应系统消息设为已读
mViewModel?.postMessageRead(gameEntity.messageId)
}
GameDetailActivity.startGameDetailActivity(
context = mActivity!!,
gameId = gameEntity.id,
entrance = "首页插件上架弹窗",
defaultTab = -1,
isSkipGameComment = false,
scrollToLibao = false,
openVideoStreaming = false,
openPlatformWindow = true,
traceEvent = null
)
}
}
BugFixedPopupWindow(
binding.root,
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT
).apply {
isTouchable = true
isFocusable = true
isOutsideTouchable = true
animationStyle = R.style.popup_window_ease_in_and_out_anim_style
showAtLocation(
mActivity!!.window.decorView,
Gravity.TOP,
0,
DisplayUtils.getStatusBarHeight(mActivity!!.resources) + DisplayUtils.dip2px(42f)
)
setOnDismissListener {
dismissCallback.invoke()
}
mBaseHandler?.postDelayed({ dismiss() }, 5000)
}
}
}

View File

@ -0,0 +1,42 @@
package com.gh.common.prioritychain
import com.gh.gamecenter.fragment.HomeSearchToolWrapperFragment
class HomePushHandler(priority: Int): PriorityChainHandler(priority) {
private var mHomeFragment: HomeSearchToolWrapperFragment? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(homeFragment: HomeSearchToolWrapperFragment?, shouldShow: Boolean) {
mHomeFragment = homeFragment
if (getStatus() == STATUS_PENDING) {
if (shouldShow && homeFragment != null) {
onProcess()
} else {
processNext()
}
} else {
if (shouldShow && homeFragment != null) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
}
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
// 目前首页下拉二楼是首页最后一个弹窗类的东西,还没实现回调,如果有其它要在它后面弹出的,需要自行在它的实现结果后添加回调
mHomeFragment?.popUpHomePushIfNeeded()
}
STATUS_INVALID -> {
processNext()
}
}
}
}

View File

@ -0,0 +1,20 @@
package com.gh.common.prioritychain
import com.gh.gamecenter.common.entity.NotificationUgc
import com.gh.gamecenter.common.utils.NotificationHelper
import com.gh.gamecenter.login.user.UserManager
class NotificationPermissionDialogHandler(priority: Int) : PriorityChainHandler(priority) {
override fun onProcess() {
// 仅登录后再启动光环时请求一次权限
if (UserManager.getInstance().isLoggedIn) {
NotificationHelper.showNotificationHintDialog(NotificationUgc.LOGIN) {
processNext()
}
} else {
processNext()
}
}
}

View File

@ -0,0 +1,20 @@
package com.gh.common.prioritychain
import java.util.*
import java.util.concurrent.PriorityBlockingQueue
class PriorityChain {
private val mHandlerQueue: Queue<PriorityChainHandler> = PriorityBlockingQueue()
fun addHandler(handler: PriorityChainHandler) {
mHandlerQueue.add(handler.also {
it.setPriorityChain(this)
})
}
fun start() {
mHandlerQueue.poll()?.process(mHandlerQueue)
}
}

View File

@ -0,0 +1,62 @@
package com.gh.common.prioritychain
import java.util.*
abstract class PriorityChainHandler(private val mPriority: Int) : Comparable<PriorityChainHandler> {
private var mStatus = STATUS_UNKNOWN
private var mQueue: Queue<PriorityChainHandler>? = null
private var mPriorityChain: PriorityChain? = null
/**
* 获取当前 handler 的状态
* - 等待结果返回 STATUS_PENDING
* - 无需执行 STATUS_INVALID
* - 可执行 STATUS_VALID
* - 未知 STATUS_UNKNOWN
*/
fun getStatus(): Int = mStatus
fun updateStatus(status: Int) {
mStatus = status
}
fun setPriorityChain(priorityChain: PriorityChain) {
mPriorityChain = priorityChain
}
fun process(queue: Queue<PriorityChainHandler>) {
mQueue = queue
// 若当前 handler 未经处理,将其状态改为 pending
if (mStatus == STATUS_UNKNOWN) {
updateStatus(STATUS_PENDING)
}
onProcess()
}
/**
* 执行相关功能的地方
*/
abstract fun onProcess()
/**
* 分发给下一个 handler 处理
*/
fun processNext() {
mQueue?.poll()?.process(mQueue!!)
}
override fun compareTo(other: PriorityChainHandler): Int {
return (mPriority - other.mPriority)
}
companion object {
internal const val STATUS_PENDING = 0
internal const val STATUS_INVALID = 1
internal const val STATUS_VALID = 2
internal const val STATUS_UNKNOWN = 3
}
}

View File

@ -0,0 +1,47 @@
package com.gh.common.prioritychain
import androidx.fragment.app.FragmentActivity
import com.gh.common.dialog.PrivacyPolicyDialogFragment
import com.gh.gamecenter.entity.DialogEntity
class PrivacyPolicyDialogHandler(priority: Int) : PriorityChainHandler(priority) {
private var mActivity: FragmentActivity? = null
private var mPrivacyPolicyEntity: DialogEntity.PrivacyPolicyEntity? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(fragmentActivity: FragmentActivity, privacyPolicyEntity: DialogEntity.PrivacyPolicyEntity?) {
mActivity = fragmentActivity
mPrivacyPolicyEntity = privacyPolicyEntity
if (getStatus() == STATUS_PENDING) {
if (privacyPolicyEntity == null) {
processNext()
} else {
onProcess()
}
} else {
if (privacyPolicyEntity == null) {
updateStatus(STATUS_INVALID)
} else {
updateStatus(STATUS_VALID)
}
}
}
override fun onProcess() {
when(getStatus()) {
STATUS_VALID -> {
PrivacyPolicyDialogFragment.show(mActivity!!, mPrivacyPolicyEntity) { _: Boolean? ->
processNext()
}
}
STATUS_INVALID -> {
processNext()
}
}
}
}

View File

@ -0,0 +1,52 @@
package com.gh.common.prioritychain
import androidx.fragment.app.Fragment
import com.gh.common.dialog.ReserveDialog
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.message.MessageUnreadRepository
class ReserveDialogHandler(priority: Int) : PriorityChainHandler(priority) {
private var mFragment: Fragment? = null
private var mReserveData: List<SimpleGameEntity>? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(fragment: Fragment, reserveData: List<SimpleGameEntity>?) {
mFragment = fragment
mReserveData = reserveData
if (getStatus() == STATUS_PENDING) {
if (reserveData.isNullOrEmpty()) {
processNext()
} else {
onProcess()
}
} else {
if (reserveData.isNullOrEmpty()) {
updateStatus(STATUS_INVALID)
} else {
updateStatus(STATUS_VALID)
}
}
}
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
val reserveDialog = ReserveDialog.getInstance(mReserveData!!)
reserveDialog.setOnDismissListener {
MessageUnreadRepository.loadMessageUnreadData()
processNext()
}
reserveDialog.show(mFragment!!.childFragmentManager, "reserveDialog")
}
STATUS_INVALID -> {
processNext()
}
}
}
}

View File

@ -0,0 +1,18 @@
package com.gh.common.prioritychain
import android.content.Context
import com.gh.gamecenter.manager.UpdateManager
class UpdateDialogHandler(context: Context, priority: Int) : PriorityChainHandler(priority) {
private val mUpdateManager = UpdateManager.getInstance(context)
override fun onProcess() {
mUpdateManager.checkUpdate(true, null)
mUpdateManager.setDismissCallback {
updateStatus(STATUS_VALID)
processNext()
}
}
}

View File

@ -0,0 +1,79 @@
package com.gh.common.prioritychain
import android.graphics.Bitmap
import androidx.fragment.app.Fragment
import com.gh.gamecenter.common.callback.BiCallback
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.entity.WelcomeDialogEntity
import com.gh.gamecenter.fragment.MainWrapperViewModel
import com.gh.gamecenter.fragment.WelcomeDialogFragment
import com.halo.assistant.HaloApp
class WelcomeDialogHandler(priority: Int): PriorityChainHandler(priority) {
private var mFragment: Fragment? = null
private var mWelcomeDialogEntity: WelcomeDialogEntity? = null
fun doPreProcess(fragment: Fragment, welcomeDialogEntity: WelcomeDialogEntity?) {
mFragment = fragment
mWelcomeDialogEntity = welcomeDialogEntity
val preLoadClosure = {
// 判断启动本次应用是否已经弹窗,不是的话弹启动弹窗
if (HaloApp.get(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false) == null) {
HaloApp.put(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false)
ImageUtils.getBitmap(mWelcomeDialogEntity!!.icon, object : BiCallback<Bitmap, Boolean> {
override fun onFirst(first: Bitmap) {
if (getStatus() == STATUS_PENDING) {
updateStatus(STATUS_VALID)
onProcess()
} else {
updateStatus(STATUS_VALID)
}
}
override fun onSecond(second: Boolean) {
processNext()
}
})
} else {
processNext()
}
}
if (getStatus() == STATUS_PENDING) {
if (welcomeDialogEntity == null) {
processNext()
} else {
preLoadClosure.invoke()
}
} else {
if (welcomeDialogEntity == null) {
updateStatus(STATUS_INVALID)
} else {
preLoadClosure.invoke()
}
}
}
override fun onProcess() {
when (getStatus()) {
STATUS_VALID -> {
if (mFragment == null || !mFragment!!.isAdded) {
updateStatus(STATUS_INVALID)
processNext()
} else {
val welcomeDialog = WelcomeDialogFragment.getInstance(mWelcomeDialogEntity)
welcomeDialog.setOnDismissListener {
processNext()
}
welcomeDialog.show(mFragment!!.childFragmentManager, "WelcomeDialog")
}
}
STATUS_INVALID -> {
processNext()
}
}
}
}