diff --git a/.idea/misc.xml b/.idea/misc.xml index b26ddeecc3..b1359dcf73 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -18,11 +18,21 @@ + + + + + + + + + + @@ -30,10 +40,14 @@ + + + + diff --git a/modules/mogo-module-push/src/main/java/com/mogo/module/push/PushModuleProvider.java b/modules/mogo-module-push/src/main/java/com/mogo/module/push/PushModuleProvider.java index 83ef3d1b42..d2f30c05d9 100644 --- a/modules/mogo-module-push/src/main/java/com/mogo/module/push/PushModuleProvider.java +++ b/modules/mogo-module-push/src/main/java/com/mogo/module/push/PushModuleProvider.java @@ -79,11 +79,6 @@ public class PushModuleProvider implements IMogoModuleProvider { @Override public void init(final Context context) { - HandlerUtils.INSTANCE.getMBgHandler().post(new Runnable() { - @Override - public void run() { - PushRepository.Companion.init(context); - } - }); + HandlerUtils.INSTANCE.getMBgHandler().post(() -> PushRepository.Companion.init(context)); } } diff --git a/modules/mogo-module-push/src/main/java/com/mogo/module/push/repository/PushRepository.kt b/modules/mogo-module-push/src/main/java/com/mogo/module/push/repository/PushRepository.kt index 827c89c747..366ca47a00 100644 --- a/modules/mogo-module-push/src/main/java/com/mogo/module/push/repository/PushRepository.kt +++ b/modules/mogo-module-push/src/main/java/com/mogo/module/push/repository/PushRepository.kt @@ -123,7 +123,9 @@ class PushRepository(mContext: Context) { } else { return } - iterateNext() + mHandler.post { + iterateNext() + } } } diff --git a/modules/mogo-module-push/src/main/java/com/mogo/module/push/view/FloatView.kt b/modules/mogo-module-push/src/main/java/com/mogo/module/push/view/FloatView.kt index af956153da..4fa54061b4 100644 --- a/modules/mogo-module-push/src/main/java/com/mogo/module/push/view/FloatView.kt +++ b/modules/mogo-module-push/src/main/java/com/mogo/module/push/view/FloatView.kt @@ -1,22 +1,15 @@ package com.mogo.module.push.view -import android.animation.Animator -import android.animation.ObjectAnimator -import android.annotation.SuppressLint import android.content.Context -import android.graphics.PixelFormat -import android.os.Build import android.os.Handler import android.os.Looper -import android.view.* +import android.view.LayoutInflater +import android.view.View import android.widget.FrameLayout -import android.widget.ImageView import android.widget.Scroller import android.widget.TextView import androidx.annotation.LayoutRes -import androidx.core.animation.doOnEnd -import androidx.core.view.isVisible -import com.elegant.analytics.utils.Logger +import com.mogo.commons.context.ContextHolderUtil import com.mogo.commons.voice.AIAssist import com.mogo.module.push.Config import com.mogo.module.push.R @@ -27,14 +20,15 @@ import com.mogo.module.push.view.roundimage.RoundedImageView import com.mogo.module.push.viewmodel.PushViewModel import com.mogo.service.windowview.IMogoTopViewManager import com.mogo.service.windowview.IMogoTopViewStatusListener -import com.mogo.utils.ResourcesHelper import com.mogo.utils.ThreadPoolService import com.mogo.utils.UiThreadHandler import com.mogo.utils.glide.GlideApp +import com.mogo.utils.logger.Logger +import kotlin.math.log class FloatView constructor( - private val pushViewModel: PushViewModel, - private val context: Context + private val pushViewModel: PushViewModel, + private val context: Context ) { companion object { @@ -46,44 +40,37 @@ class FloatView constructor( interface PushViewController { fun show(bean: PushBean?) fun hide() - fun timer(time: Int) fun inflateView(@LayoutRes layoutId: Int) } abstract inner class PushView(context: Context) : FrameLayout(context), - PushViewController { - private lateinit var appIcon: ImageView + PushViewController { private lateinit var titleIconContainer: View private lateinit var pushTitle: TextView private lateinit var pushImage: RoundedImageView private lateinit var pushContent: TextView - private lateinit var pushTimer: TextView - private lateinit var pushButtonLeft: TextView - private lateinit var pushButtonRight: TextView - lateinit var pushButton: View + private lateinit var pushCheck: TextView + + private var pushData: PushBean? = null override fun inflateView(layoutId: Int) { LayoutInflater.from(context).inflate(layoutId, this, true) - appIcon = findViewById(R.id.module_push_app_icon) pushTitle = findViewById(R.id.module_push_title) + pushCheck = findViewById(R.id.module_push_check) pushImage = findViewById(R.id.module_push_image) pushContent = findViewById(R.id.module_push_content) - pushButtonLeft = findViewById(R.id.module_push_button_left) - pushButtonRight = findViewById(R.id.module_push_button_right) - pushTimer = findViewById(R.id.module_push_timer) titleIconContainer = findViewById(R.id.module_push_app_icon_title) - pushButton = findViewById(R.id.module_push_buttons) setOnClickListener { pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_MAIN, "1") turnNextMessage() } - pushButtonLeft.setOnClickListener { - pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_LEFT, "1") - turnNextMessage() - } - pushButtonRight.setOnClickListener { - pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_RIGHT, "1") - turnNextMessage() + pushCheck.setOnClickListener { + pushData?.let { + if (pushCheckDialog == null) { + pushCheckDialog = PushCheckDialog(ContextHolderUtil.getContext()) + } + pushCheckDialog!!.showCheckDialog(it.title, it.content) + } } } @@ -94,35 +81,11 @@ class FloatView constructor( } } - fun hasButtons(bean: PushBean?): Boolean { - bean?.buttons?.forEach { - if (it.text.isNotEmpty()) { - return true - } - } - return false - } - - fun hasTextContent(bean: PushBean?): Boolean = - bean?.content?.isEmpty()?.not() ?: false - - fun hasImgContent(bean: PushBean?): Boolean = bean?.QRCode?.isEmpty()?.not() ?: false - open fun setBean(bean: PushBean) { - // app icon - if (bean.appIcon.isNotEmpty()) { - appIcon.visible() - GlideApp.with(this).load(bean.appIcon).into(appIcon) - } else { - appIcon.gone() - } - + pushData = bean // title pushTitle.text = bean.title - // decrease timer - pushTimer.text = if (bean.showTimeout > 99) "" else "${bean.showTimeout}s" - // image if (bean.imageUrl.isEmpty() && bean.QRCode.isEmpty()) { pushImage.gone() @@ -140,9 +103,9 @@ class FloatView constructor( pushImage.layoutParams = params ThreadPoolService.execute { val bmp = stringConverterBitmap( - bean.QRCode, - getQrImgWidth(), - getQrImgHeight() + bean.QRCode, + getQrImgWidth(), + getQrImgHeight() ) UiThreadHandler.post { pushImage.setImageBitmap(bmp) @@ -151,22 +114,6 @@ class FloatView constructor( } } - // button - pushButton.gone() - pushButtonLeft.gone() - pushButtonRight.gone() - if (!bean.buttons.isNullOrEmpty()) { - if (bean.buttons[0].text.isNotEmpty()) { - pushButton.visible() - pushButtonLeft.text = bean.buttons[0].text - pushButtonLeft.visible() - } - if (bean.buttons.size > 1 && bean.buttons[1].text.isNotEmpty()) { - pushButtonRight.text = bean.buttons[1].text - pushButtonRight.visible() - } - } - // content if (bean.content.isEmpty()) { pushContent.gone() @@ -186,12 +133,6 @@ class FloatView constructor( abstract fun getQrImgWidth(): Int abstract fun getQrImgHeight(): Int - @SuppressLint("SetTextI18n") - override fun timer(time: Int) { - Logger.d(TAG, "time = $time") - pushTimer.text = "${time}s" - } - override fun show(bean: PushBean?) { isAddWindow = true uiHandler.removeCallbacks(delayClosePush) @@ -252,184 +193,175 @@ class FloatView constructor( } override fun getImgWidth(): Int = - context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width) + context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width) override fun getImgHeight(): Int = - context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height) + context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height) override fun getQrImgWidth(): Int = - context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height) + context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height) override fun getQrImgHeight(): Int = - context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height) + context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height) } - inner class PushViewInWindowView(context: Context) : PushView(context), View.OnTouchListener { - - private val mContentContainer: View - private val mWindowManager = - context.getSystemService(Context.WINDOW_SERVICE) as WindowManager - - private val params = WindowManager.LayoutParams() - - init { - - @Suppress("DEPRECATION") - params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT - params.flags = (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION - or WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE - or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH - or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) - params.width = WindowManager.LayoutParams.WRAP_CONTENT - params.height = WindowManager.LayoutParams.WRAP_CONTENT - params.gravity = Gravity.START or Gravity.BOTTOM - params.format = PixelFormat.TRANSLUCENT - params.x = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x) - params.y = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x) - if (Build.VERSION.SDK_INT > 25) { - params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY - } - - inflateView(R.layout.module_push_item_vertical) - mContentContainer = findViewById(R.id.module_push_content_container) - setOnTouchListener(this) - } - - override fun show(bean: PushBean?) { - super.show(bean) - mLastVisibleType = TYPE_WINDOW_MANAGER - setBean(bean!!) - - try { - mWindowManager.addView(this, params) - } catch (e: Exception) { - mWindowManager.updateViewLayout(this, params) - } - translationXAnimation( - -ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical), - 0f - ) { - if (pushViewModel.pushBean != null) { - startClosePush() - } - } - } - - private fun translationXAnimation( - from: Float, - to: Float, - doOnEnd: (animator: Animator) -> Unit - ) { - val transitionXAnimator: ObjectAnimator = - ObjectAnimator.ofFloat( - this, - View.TRANSLATION_X, - from, - to - ) - transitionXAnimator.duration = 200 - transitionXAnimator.doOnEnd(doOnEnd) - transitionXAnimator.start() - } - - override fun setBean(bean: PushBean) { - super.setBean(bean) - var paddingBottom = 0 - if (pushButton.isVisible) { - paddingBottom = - context.resources.getDimensionPixelSize(R.dimen.module_push_content_paddingBottom_vertical) - } - mContentContainer.setPadding(0, 0, 0, paddingBottom) - } - - override fun hide() { - super.hide() - translationXAnimation( - this.x, - -ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical) - ) { - Logger.d(TAG, "here") - this.x = 0f - mWindowManager.removeViewImmediate(this) - } - } - - override fun onTouch(v: View?, ev: MotionEvent?): Boolean { - - if (mLastVisibleType != TYPE_WINDOW_MANAGER) { - return false - } - when (ev?.action) { - MotionEvent.ACTION_DOWN -> { - needInterceptClick = false - startX = ev.x - } - MotionEvent.ACTION_MOVE -> { - moveX = startX - ev.x - scrollBy(moveX.toInt(), 0) - startX = ev.x - if (scrollX < 0) { - scrollTo(0, 0) - } - if (!needInterceptClick && scrollX > 20) { - needInterceptClick = true - } - invalidate() - } - MotionEvent.ACTION_UP -> { - if (scrollX > 0) { - mScroller.startScroll(scrollX, 0, width - scrollX, 0) - invalidate() - return true - } - if (needInterceptClick) { - return true - } - } - else -> { - startX = 0f - moveX = 0f - } - } - return false - } - - override fun computeScroll() { - if (mScroller.computeScrollOffset()) { - scrollTo(mScroller.currX, mScroller.currY) - invalidate() - } else { - if (mScroller.currX == 0) { - return - } - mScroller.finalX = 0 - removeCallbacks(delayClosePush) - if (isAddWindow) { - if (currentBean != null) { - AnalyticsUtils.track(Config.NEWS_CARD_SWIPE, "trigger_type", "1") - } - mWindowManager.removeView(this) - isAddWindow = false - } - pushViewModel.pushBean?.showTimeout = 0 - updateTimer() - } - } - - override fun getImgWidth(): Int = - context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width_vertical) - - override fun getImgHeight(): Int = - context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height_vertical) - - override fun getQrImgWidth(): Int = - context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical) - - override fun getQrImgHeight(): Int = - context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical) - } +// inner class PushViewInWindowView(context: Context) : PushView(context), View.OnTouchListener { +// +// private val mContentContainer: View +// private val mWindowManager = +// context.getSystemService(Context.WINDOW_SERVICE) as WindowManager +// +// private val params = WindowManager.LayoutParams() +// +// init { +// +// @Suppress("DEPRECATION") +// params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT +// params.flags = (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN +// or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION +// or WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE +// or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH +// or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) +// params.width = WindowManager.LayoutParams.WRAP_CONTENT +// params.height = WindowManager.LayoutParams.WRAP_CONTENT +// params.gravity = Gravity.START or Gravity.BOTTOM +// params.format = PixelFormat.TRANSLUCENT +// params.x = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x) +// params.y = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x) +// if (Build.VERSION.SDK_INT > 25) { +// params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY +// } +// +// inflateView(R.layout.module_push_item_vertical) +// mContentContainer = findViewById(R.id.module_push_content_container) +// setOnTouchListener(this) +// } +// +// override fun show(bean: PushBean?) { +// super.show(bean) +// mLastVisibleType = TYPE_WINDOW_MANAGER +// setBean(bean!!) +// +// try { +// mWindowManager.addView(this, params) +// } catch (e: Exception) { +// mWindowManager.updateViewLayout(this, params) +// } +// translationXAnimation( +// -ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical), +// 0f +// ) { +// if (pushViewModel.pushBean != null) { +// startClosePush() +// } +// } +// } +// +// private fun translationXAnimation( +// from: Float, +// to: Float, +// doOnEnd: (animator: Animator) -> Unit +// ) { +// val transitionXAnimator: ObjectAnimator = +// ObjectAnimator.ofFloat( +// this, +// View.TRANSLATION_X, +// from, +// to +// ) +// transitionXAnimator.duration = 200 +// transitionXAnimator.doOnEnd(doOnEnd) +// transitionXAnimator.start() +// } +// +// override fun hide() { +// super.hide() +// translationXAnimation( +// this.x, +// -ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical) +// ) { +// Logger.d(TAG, "here") +// this.x = 0f +// mWindowManager.removeViewImmediate(this) +// } +// } +// +// override fun onTouch(v: View?, ev: MotionEvent?): Boolean { +// +// if (mLastVisibleType != TYPE_WINDOW_MANAGER) { +// return false +// } +// when (ev?.action) { +// MotionEvent.ACTION_DOWN -> { +// needInterceptClick = false +// startX = ev.x +// } +// MotionEvent.ACTION_MOVE -> { +// moveX = startX - ev.x +// scrollBy(moveX.toInt(), 0) +// startX = ev.x +// if (scrollX < 0) { +// scrollTo(0, 0) +// } +// if (!needInterceptClick && scrollX > 20) { +// needInterceptClick = true +// } +// invalidate() +// } +// MotionEvent.ACTION_UP -> { +// if (scrollX > 0) { +// mScroller.startScroll(scrollX, 0, width - scrollX, 0) +// invalidate() +// return true +// } +// if (needInterceptClick) { +// return true +// } +// } +// else -> { +// startX = 0f +// moveX = 0f +// } +// } +// return false +// } +// +// override fun computeScroll() { +// if (mScroller.computeScrollOffset()) { +// scrollTo(mScroller.currX, mScroller.currY) +// invalidate() +// } else { +// if (mScroller.currX == 0) { +// return +// } +// mScroller.finalX = 0 +// removeCallbacks(delayClosePush) +// if (isAddWindow) { +// if (currentBean != null) { +// AnalyticsUtils.track(Config.NEWS_CARD_SWIPE, "trigger_type", "1") +// } +// mWindowManager.removeView(this) +// isAddWindow = false +// } +// pushViewModel.pushBean?.showTimeout = 0 +// updateTimer() +// } +// } +// +// override fun getImgWidth(): Int = +// context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width_vertical) +// +// override fun getImgHeight(): Int = +// context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height_vertical) +// +// override fun getQrImgWidth(): Int = +// context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical) +// +// override fun getQrImgHeight(): Int = +// context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical) +// } + private var pushCheckDialog: PushCheckDialog? = null private val delayClosePush: Runnable private var isAddWindow = false private val uiHandler = Handler(Looper.getMainLooper()) @@ -473,10 +405,8 @@ class FloatView constructor( val time = pushViewModel.pushBean?.showTimeout ?: 0 if (time > 0) { pushViewModel.pushBean!!.showTimeout-- - pushViewController?.timer(time) uiHandler.postDelayed(delayClosePush, 1000) } else { - pushViewController?.timer(0) pushViewModel.pushMessageFinish(true) } } @@ -520,17 +450,17 @@ class FloatView constructor( } private fun showByWindowManager(bean: PushBean?) { - if (pushViewController !is PushViewInWindowView) { - pushViewController = PushViewInWindowView(context) - } - pushViewController?.show(bean) +// if (pushViewController !is PushViewInWindowView) { +// pushViewController = PushViewInWindowView(context) +// } +// pushViewController?.show(bean) } private fun startClosePush() { uiHandler.removeCallbacks(delayClosePush) uiHandler.postDelayed( - delayClosePush, - 1000L + delayClosePush, + 1000L ) } diff --git a/modules/mogo-module-push/src/main/java/com/mogo/module/push/view/FloatViewOrigin.kt b/modules/mogo-module-push/src/main/java/com/mogo/module/push/view/FloatViewOrigin.kt new file mode 100644 index 0000000000..d2b24659c9 --- /dev/null +++ b/modules/mogo-module-push/src/main/java/com/mogo/module/push/view/FloatViewOrigin.kt @@ -0,0 +1,568 @@ +package com.mogo.module.push.view + +import android.animation.Animator +import android.animation.ObjectAnimator +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.PixelFormat +import android.os.Build +import android.os.Handler +import android.os.Looper +import android.view.* +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.Scroller +import android.widget.TextView +import androidx.annotation.LayoutRes +import androidx.core.animation.doOnEnd +import androidx.core.view.isVisible +import com.elegant.analytics.utils.Logger +import com.mogo.commons.voice.AIAssist +import com.mogo.module.push.Config +import com.mogo.module.push.R +import com.mogo.module.push.model.PushBean +import com.mogo.module.push.utils.AnalyticsUtils +import com.mogo.module.push.utils.stringConverterBitmap +import com.mogo.module.push.view.roundimage.RoundedImageView +import com.mogo.module.push.viewmodel.PushViewModel +import com.mogo.service.windowview.IMogoTopViewManager +import com.mogo.service.windowview.IMogoTopViewStatusListener +import com.mogo.utils.ResourcesHelper +import com.mogo.utils.ThreadPoolService +import com.mogo.utils.UiThreadHandler +import com.mogo.utils.glide.GlideApp + +class FloatViewOrigin constructor( + private val pushViewModel: PushViewModel, + private val context: Context +) { + + companion object { + const val TYPE_TOP_VIEW = 1 + const val TYPE_WINDOW_MANAGER = 2 + const val TAG: String = "FloatViewOrigin.kt" + } + + interface PushViewController { + fun show(bean: PushBean?) + fun hide() + fun timer(time: Int) + fun inflateView(@LayoutRes layoutId: Int) + } + + abstract inner class PushViewOrigin(context: Context) : FrameLayout(context), + PushViewController { + private lateinit var appIcon: ImageView + private lateinit var titleIconContainer: View + private lateinit var pushTitle: TextView + private lateinit var pushImage: RoundedImageView + private lateinit var pushContent: TextView + private lateinit var pushTimer: TextView + private lateinit var pushButtonLeft: TextView + private lateinit var pushButtonRight: TextView + lateinit var pushButton: View + + override fun inflateView(layoutId: Int) { + LayoutInflater.from(context).inflate(layoutId, this, true) + appIcon = findViewById(R.id.module_push_app_icon) + pushTitle = findViewById(R.id.module_push_title) + pushImage = findViewById(R.id.module_push_image) + pushContent = findViewById(R.id.module_push_content) + pushButtonLeft = findViewById(R.id.module_push_button_left) + pushButtonRight = findViewById(R.id.module_push_button_right) + pushTimer = findViewById(R.id.module_push_timer) + titleIconContainer = findViewById(R.id.module_push_app_icon_title) + pushButton = findViewById(R.id.module_push_buttons) + setOnClickListener { + pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_MAIN, "1") + turnNextMessage() + } + pushButtonLeft.setOnClickListener { + pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_LEFT, "1") + turnNextMessage() + } + pushButtonRight.setOnClickListener { + pushViewModel.dealCmd(PushViewModel.VOICE_ACTION_PUSH_RIGHT, "1") + turnNextMessage() + } + } + + private fun turnNextMessage() { + pushViewModel.pushBean?.apply { + showTimeout = 0 + updateTimer() + } + } + + fun hasButtons(bean: PushBean?): Boolean { + bean?.buttons?.forEach { + if (it.text.isNotEmpty()) { + return true + } + } + return false + } + + fun hasTextContent(bean: PushBean?): Boolean = + bean?.content?.isEmpty()?.not() ?: false + + fun hasImgContent(bean: PushBean?): Boolean = bean?.QRCode?.isEmpty()?.not() ?: false + + open fun setBean(bean: PushBean) { + // app icon + if (bean.appIcon.isNotEmpty()) { + appIcon.visible() + GlideApp.with(this).load(bean.appIcon).into(appIcon) + } else { + appIcon.gone() + } + + // title + pushTitle.text = bean.title + + // decrease timer + pushTimer.text = if (bean.showTimeout > 99) "" else "${bean.showTimeout}s" + + // image + if (bean.imageUrl.isEmpty() && bean.QRCode.isEmpty()) { + pushImage.gone() + } else if (bean.imageUrl.isNotEmpty()) { + val params = pushImage.layoutParams + params.width = getImgWidth() + params.height = getImgHeight() + pushImage.layoutParams = params + pushImage.visible() + GlideApp.with(this).load(bean.imageUrl).into(pushImage) + } else if (bean.QRCode.isNotEmpty()) { + val params = pushImage.layoutParams + params.width = getQrImgWidth() + params.height = getQrImgHeight() + pushImage.layoutParams = params + ThreadPoolService.execute { + val bmp = stringConverterBitmap( + bean.QRCode, + getQrImgWidth(), + getQrImgHeight() + ) + UiThreadHandler.post { + pushImage.setImageBitmap(bmp) + pushImage.visible() + } + } + } + + // button + pushButton.gone() + pushButtonLeft.gone() + pushButtonRight.gone() + if (!bean.buttons.isNullOrEmpty()) { + if (bean.buttons[0].text.isNotEmpty()) { + pushButton.visible() + pushButtonLeft.text = bean.buttons[0].text + pushButtonLeft.visible() + } + if (bean.buttons.size > 1 && bean.buttons[1].text.isNotEmpty()) { + pushButtonRight.text = bean.buttons[1].text + pushButtonRight.visible() + } + } + + // content + if (bean.content.isEmpty()) { + pushContent.gone() + } else { + pushContent.text = bean.content + pushContent.visible() + } + + // tts + if (bean.tts.isNotEmpty()) { + AIAssist.getInstance(context).speakTTSVoice(bean.tts) + } + } + + abstract fun getImgWidth(): Int + abstract fun getImgHeight(): Int + abstract fun getQrImgWidth(): Int + abstract fun getQrImgHeight(): Int + + @SuppressLint("SetTextI18n") + override fun timer(time: Int) { + Logger.d(TAG, "time = $time") + pushTimer.text = "${time}s" + } + + override fun show(bean: PushBean?) { + isAddWindow = true + uiHandler.removeCallbacks(delayClosePush) + } + + override fun hide() { + isAddWindow = false + } + } + + open inner class PushViewInTopView(context: Context) : PushViewOrigin(context) { + + private val mTopViewManager: IMogoTopViewManager = getApis(context).topViewManager + + init { + inflateView(R.layout.module_push_item_origin) + } + + private var topViewStatusListener = object : IMogoTopViewStatusListener { + override fun onViewRemoved(view: View?) { + isAddWindow = false + if (pushViewModel.pushBean?.showTimeout ?: 0 > 0) { + if (getApis(context).statusManagerApi.isV2XShow) { + // 被中断的消息,需要再次被显示一次 + uiHandler.removeCallbacks(delayClosePush) + pushViewModel.push() + pushViewModel.pushMessageFinish() + return + } + } + pushViewModel.pushBean?.showTimeout = 0 + updateTimer() + } + + override fun onViewAdded(view: View?) { + if (pushViewModel.pushBean != null) { + startClosePush() + } + } + + override fun beforeViewRemoveAnim(view: View?) { + } + + override fun beforeViewAddAnim(view: View?) { + } + } + + override fun show(bean: PushBean?) { + super.show(bean) + mLastVisibleType = TYPE_TOP_VIEW + mTopViewManager.addView(this, topViewStatusListener) + setBean(bean!!) + } + + override fun hide() { + super.hide() + mTopViewManager.removeView(this) + } + + override fun getImgWidth(): Int = + context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width) + + override fun getImgHeight(): Int = + context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height) + + override fun getQrImgWidth(): Int = + context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height) + + override fun getQrImgHeight(): Int = + context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height) + } + + inner class PushViewInWindowView(context: Context) : PushViewOrigin(context), View.OnTouchListener { + + private val mContentContainer: View + private val mWindowManager = + context.getSystemService(Context.WINDOW_SERVICE) as WindowManager + + private val params = WindowManager.LayoutParams() + + init { + + @Suppress("DEPRECATION") + params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT + params.flags = (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION + or WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE + or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH + or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) + params.width = WindowManager.LayoutParams.WRAP_CONTENT + params.height = WindowManager.LayoutParams.WRAP_CONTENT + params.gravity = Gravity.START or Gravity.BOTTOM + params.format = PixelFormat.TRANSLUCENT + params.x = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x) + params.y = context.resources.getDimensionPixelSize(R.dimen.module_push_window_x) + if (Build.VERSION.SDK_INT > 25) { + params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY + } + + inflateView(R.layout.module_push_item_vertical) + mContentContainer = findViewById(R.id.module_push_content_container) + setOnTouchListener(this) + } + + override fun show(bean: PushBean?) { + super.show(bean) + mLastVisibleType = TYPE_WINDOW_MANAGER + setBean(bean!!) + + try { + mWindowManager.addView(this, params) + } catch (e: Exception) { + mWindowManager.updateViewLayout(this, params) + } + translationXAnimation( + -ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical), + 0f + ) { + if (pushViewModel.pushBean != null) { + startClosePush() + } + } + } + + private fun translationXAnimation( + from: Float, + to: Float, + doOnEnd: (animator: Animator) -> Unit + ) { + val transitionXAnimator: ObjectAnimator = + ObjectAnimator.ofFloat( + this, + View.TRANSLATION_X, + from, + to + ) + transitionXAnimator.duration = 200 + transitionXAnimator.doOnEnd(doOnEnd) + transitionXAnimator.start() + } + + override fun setBean(bean: PushBean) { + super.setBean(bean) + var paddingBottom = 0 + if (pushButton.isVisible) { + paddingBottom = + context.resources.getDimensionPixelSize(R.dimen.module_push_content_paddingBottom_vertical) + } + mContentContainer.setPadding(0, 0, 0, paddingBottom) + } + + override fun hide() { + super.hide() + translationXAnimation( + this.x, + -ResourcesHelper.getDimension(context, R.dimen.module_push_ui_width_vertical) + ) { + Logger.d(TAG, "here") + this.x = 0f + mWindowManager.removeViewImmediate(this) + } + } + + override fun onTouch(v: View?, ev: MotionEvent?): Boolean { + + if (mLastVisibleType != TYPE_WINDOW_MANAGER) { + return false + } + when (ev?.action) { + MotionEvent.ACTION_DOWN -> { + needInterceptClick = false + startX = ev.x + } + MotionEvent.ACTION_MOVE -> { + moveX = startX - ev.x + scrollBy(moveX.toInt(), 0) + startX = ev.x + if (scrollX < 0) { + scrollTo(0, 0) + } + if (!needInterceptClick && scrollX > 20) { + needInterceptClick = true + } + invalidate() + } + MotionEvent.ACTION_UP -> { + if (scrollX > 0) { + mScroller.startScroll(scrollX, 0, width - scrollX, 0) + invalidate() + return true + } + if (needInterceptClick) { + return true + } + } + else -> { + startX = 0f + moveX = 0f + } + } + return false + } + + override fun computeScroll() { + if (mScroller.computeScrollOffset()) { + scrollTo(mScroller.currX, mScroller.currY) + invalidate() + } else { + if (mScroller.currX == 0) { + return + } + mScroller.finalX = 0 + removeCallbacks(delayClosePush) + if (isAddWindow) { + if (currentBean != null) { + AnalyticsUtils.track(Config.NEWS_CARD_SWIPE, "trigger_type", "1") + } + mWindowManager.removeView(this) + isAddWindow = false + } + pushViewModel.pushBean?.showTimeout = 0 + updateTimer() + } + } + + override fun getImgWidth(): Int = + context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_width_vertical) + + override fun getImgHeight(): Int = + context.resources.getDimensionPixelSize(R.dimen.module_push_ui_image_height_vertical) + + override fun getQrImgWidth(): Int = + context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical) + + override fun getQrImgHeight(): Int = + context.resources.getDimensionPixelSize(R.dimen.module_push_image_qr_size_vertical) + } + + private val delayClosePush: Runnable + private var isAddWindow = false + private val uiHandler = Handler(Looper.getMainLooper()) + + private var startX = 0f + private var moveX = 0f + private val mScroller: Scroller = Scroller(context) + private var needInterceptClick = false + private var pause = false + + private var currentBean: PushBean? = null + + + private var mLastVisibleType = -1 + private var pushViewController: PushViewController? = null + + init { + delayClosePush = Runnable { + updateTimer() + } + } + + fun pushBeanChanged(bean: PushBean?) { + uiHandler.post { + uiHandler.removeCallbacks(delayClosePush) + if (bean == null) { + if (currentBean != null) { + AnalyticsUtils.track(Config.NEWS_CARD_DISAPPEAR, "title", currentBean!!.title) + } + hide() + } else { + show(bean) + AnalyticsUtils.track(Config.NEWS_CARD_SHOW, "title", bean.title) + } + currentBean = bean + } + } + + private fun updateTimer() { + uiHandler.removeCallbacks(delayClosePush) + val time = pushViewModel.pushBean?.showTimeout ?: 0 + if (time > 0) { + pushViewModel.pushBean!!.showTimeout-- + pushViewController?.timer(time) + uiHandler.postDelayed(delayClosePush, 1000) + } else { + pushViewController?.timer(0) + pushViewModel.pushMessageFinish(true) + } + } + + private fun show(bean: PushBean) { + if (isAddWindow) { + if (getApis(context).statusManagerApi.isMainPageOnResume) { + if (mLastVisibleType != TYPE_TOP_VIEW) { + hide() + (pushViewController as View).postDelayed({ + show(bean) + }, 750L) + } else { + showByTopView(bean) + } + } else { + if (mLastVisibleType != TYPE_WINDOW_MANAGER) { + hide() + (pushViewController as View).postDelayed({ + show(bean) + }, 750L) + } else { + showByWindowManager(bean) + } + } + startClosePush() + } else { + if (getApis(context).statusManagerApi.isMainPageOnResume) { + showByTopView(bean) + } else { + showByWindowManager(bean) + } + } + } + + private fun showByTopView(bean: PushBean) { + if (pushViewController !is PushViewInTopView) { + pushViewController = PushViewInTopView(context) + } + pushViewController?.show(bean) + } + + private fun showByWindowManager(bean: PushBean?) { + if (pushViewController !is PushViewInWindowView) { + pushViewController = PushViewInWindowView(context) + } + pushViewController?.show(bean) + } + + private fun startClosePush() { + uiHandler.removeCallbacks(delayClosePush) + uiHandler.postDelayed( + delayClosePush, + 1000L + ) + } + + + fun hide() { + if (!isAddWindow) { + return + } + try { + pushViewController?.hide() + } catch (e: Exception) { + e.printStackTrace() + } + } + + + fun pauseTimer(on: Boolean) { + if (on) { + uiHandler.removeCallbacks(delayClosePush) + } else { + updateTimer() + uiHandler.post { + if (on) { + pause = true + uiHandler.removeCallbacks(delayClosePush) + } else if (pause) { + pause = false + updateTimer() + } + } + } + } + + fun isAddWindow(): Boolean = isAddWindow +} \ No newline at end of file diff --git a/modules/mogo-module-push/src/main/java/com/mogo/module/push/view/PushCheckDialog.kt b/modules/mogo-module-push/src/main/java/com/mogo/module/push/view/PushCheckDialog.kt new file mode 100644 index 0000000000..8d4f47a7c2 --- /dev/null +++ b/modules/mogo-module-push/src/main/java/com/mogo/module/push/view/PushCheckDialog.kt @@ -0,0 +1,37 @@ +package com.mogo.module.push.view + +import android.content.Context +import android.widget.ImageView +import android.widget.TextView +import com.mogo.module.common.dialog.BaseFloatDialog +import com.mogo.module.push.R + +class PushCheckDialog(context: Context) : BaseFloatDialog(context) { + + private var pushCheckClose: ImageView? = null + private var pushCheckTitle: TextView? = null + private var pushCheckContent: TextView? = null + + init { + setContentView(R.layout.module_push_dialog_check) + setCanceledOnTouchOutside(true) + pushCheckClose = findViewById(R.id.module_push_dialog_close) + pushCheckTitle = findViewById(R.id.module_push_dialog_title) + pushCheckContent = findViewById(R.id.module_push_dialog_content) + pushCheckClose?.setOnClickListener { + dismiss() + } + } + + fun showCheckDialog(title: String, content: String) { + if (isShowing) { + return + } + if (title.isBlank() || content.isBlank()) { + return + } + pushCheckTitle?.text = title + pushCheckContent?.text = content + show() + } +} \ No newline at end of file diff --git a/modules/mogo-module-push/src/main/res/drawable-xhdpi/module_push_dialog_close.png b/modules/mogo-module-push/src/main/res/drawable-xhdpi/module_push_dialog_close.png new file mode 100644 index 0000000000..95a08f52f4 Binary files /dev/null and b/modules/mogo-module-push/src/main/res/drawable-xhdpi/module_push_dialog_close.png differ diff --git a/modules/mogo-module-push/src/main/res/drawable/module_push_dialog_check_background.xml b/modules/mogo-module-push/src/main/res/drawable/module_push_dialog_check_background.xml new file mode 100644 index 0000000000..4d721f27c8 --- /dev/null +++ b/modules/mogo-module-push/src/main/res/drawable/module_push_dialog_check_background.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/modules/mogo-module-push/src/main/res/drawable/module_push_item_backgroud.xml b/modules/mogo-module-push/src/main/res/drawable/module_push_item_backgroud.xml new file mode 100644 index 0000000000..54f571d1e5 --- /dev/null +++ b/modules/mogo-module-push/src/main/res/drawable/module_push_item_backgroud.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/modules/mogo-module-push/src/main/res/layout/module_push_dialog_check.xml b/modules/mogo-module-push/src/main/res/layout/module_push_dialog_check.xml new file mode 100644 index 0000000000..8b13014fe8 --- /dev/null +++ b/modules/mogo-module-push/src/main/res/layout/module_push_dialog_check.xml @@ -0,0 +1,43 @@ + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-push/src/main/res/layout/module_push_item.xml b/modules/mogo-module-push/src/main/res/layout/module_push_item.xml index f43312ef3f..2fe587fe28 100644 --- a/modules/mogo-module-push/src/main/res/layout/module_push_item.xml +++ b/modules/mogo-module-push/src/main/res/layout/module_push_item.xml @@ -4,18 +4,18 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="@dimen/module_push_ui_height" - android:background="@drawable/module_push_item_background_p"> + android:background="@drawable/module_push_item_backgroud"> + app:riv_corner_radius_bottom_left="@dimen/module_push_ui_image_corner" + app:riv_corner_radius_top_left="@dimen/module_push_ui_image_corner" /> - - + app:layout_constrainedWidth="true" + tools:text="官方公告" /> - + android:textSize="@dimen/module_push_ui_title_text_size" /> - - - - - - - + - - + \ No newline at end of file diff --git a/modules/mogo-module-push/src/main/res/layout/module_push_item_origin.xml b/modules/mogo-module-push/src/main/res/layout/module_push_item_origin.xml new file mode 100644 index 0000000000..f43312ef3f --- /dev/null +++ b/modules/mogo-module-push/src/main/res/layout/module_push_item_origin.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-push/src/main/res/values-xhdpi-2560x1440/dimens.xml b/modules/mogo-module-push/src/main/res/values-xhdpi-2560x1440/dimens.xml new file mode 100644 index 0000000000..afd2948b13 --- /dev/null +++ b/modules/mogo-module-push/src/main/res/values-xhdpi-2560x1440/dimens.xml @@ -0,0 +1,38 @@ + + + + 230px + 230px + 230px + 30px + 21px + 34px + 33px + 2px + 120px + 30px + 55px + 42px + 208px + 394px + 42px + 567px + 100px + 20px + 34px + 34px + + + 1200px + 763px + 32px + 107px + 107px + 40px + 54px + 56px + 1000px + 33px + 43px + + \ No newline at end of file diff --git a/modules/mogo-module-push/src/main/res/values/colors.xml b/modules/mogo-module-push/src/main/res/values/colors.xml index cd5df39f48..d01c09cbad 100644 --- a/modules/mogo-module-push/src/main/res/values/colors.xml +++ b/modules/mogo-module-push/src/main/res/values/colors.xml @@ -4,4 +4,7 @@ #FFFFFF #B2FFFFFF #999999 + #B3FFFFFF + #5A8EFD + #E63B4577 \ No newline at end of file diff --git a/modules/mogo-module-push/src/main/res/values/dimens.xml b/modules/mogo-module-push/src/main/res/values/dimens.xml index 06dbe9cde9..c958b53e35 100644 --- a/modules/mogo-module-push/src/main/res/values/dimens.xml +++ b/modules/mogo-module-push/src/main/res/values/dimens.xml @@ -98,4 +98,28 @@ 118px 86px 8px + + + 34px + 567px + 100px + + 2px + 120px + 30px + 55px + 42px + 208px + + 1200px + 763px + 32px + 107px + 107px + 40px + 54px + 56px + 1000px + 33px + 43px \ No newline at end of file diff --git a/modules/mogo-module-push/src/main/res/values/strings.xml b/modules/mogo-module-push/src/main/res/values/strings.xml index c873da000f..808d1e2474 100644 --- a/modules/mogo-module-push/src/main/res/values/strings.xml +++ b/modules/mogo-module-push/src/main/res/values/strings.xml @@ -3,4 +3,5 @@ 清除 清空历史消息 暂无消息 + 查看