[feedback]添加主动场景内置并优化数据加载逻辑

This commit is contained in:
renwj
2022-03-18 14:09:06 +08:00
parent b08ae8641f
commit c366eb37eb
15 changed files with 125 additions and 62 deletions

View File

@@ -14,6 +14,7 @@ import androidx.lifecycle.lifecycleScope
import com.mogo.cloud.passport.MoGoAiCloudClientConfig import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.utilcode.kotlin.PX
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.kotlin.lifecycleOwner import com.mogo.eagle.core.utilcode.kotlin.lifecycleOwner
import com.mogo.eagle.core.utilcode.kotlin.onClick import com.mogo.eagle.core.utilcode.kotlin.onClick
@@ -251,7 +252,12 @@ internal object BadCaseManager : LifecycleEventObserver {
val context = viewHolder?.get()?.context ?: Utils.getApp() val context = viewHolder?.get()?.context ?: Utils.getApp()
BadCaseView(context).also { itx -> BadCaseView(context).also { itx ->
itx.register(record, onDismiss, onSelect) itx.register(record, onDismiss, onSelect)
hideFloat = CallerHmiManager.showFloatWindow("BadCaseFloat", floatView = itx, WindowManager.LayoutParams().also { it.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE}) CallerHmiManager.showFloatWindow("BadCaseFloat", floatView = itx, WindowManager.LayoutParams().also {
it.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
}
).also {
hideFloat = it
}
} }
} }

View File

@@ -58,7 +58,7 @@ internal class BadCaseView: ConstraintLayout {
LayoutInflater.from(context).inflate(R.layout.layout_badcase_collect, this, true) LayoutInflater.from(context).inflate(R.layout.layout_badcase_collect, this, true)
background = ColorDrawable(Color.parseColor("#F0151D41")) background = ColorDrawable(Color.parseColor("#F0151D41"))
isClickable = true isClickable = true
layoutParams = ViewGroup.LayoutParams(960.PX, 1528.PX) layoutParams = ViewGroup.LayoutParams(960.PX, 1600.PX)
close?.onClick { close?.onClick {
onDismiss?.invoke() onDismiss?.invoke()
} }

View File

@@ -26,7 +26,21 @@ internal class Repository {
} }
suspend fun loadBadCases(isDriven: Boolean): List<Reason> { suspend fun loadBadCases(isDriven: Boolean): List<Reason> {
return net.get()?.data?.takeIf { it.isNotEmpty() }?.also { store.updateRecords(it, isDriven) } ?: store.records(isDriven).takeIf { it.isNotEmpty() } ?: getBuildIn(isDriven) return mutableListOf<Reason>().also { itx ->
net.get(if (isDriven) "被动" else "主动", itx, 1)
itx
.takeIf { it.isNotEmpty() }
?.also {
store.updateRecords(it, isDriven)
}
?:
store
.records(isDriven)
.takeIf {
it.isNotEmpty()
}
?: getBuildIn(isDriven)
}
} }
suspend fun uploadLastModified(timestamp: Long) { suspend fun uploadLastModified(timestamp: Long) {
@@ -34,7 +48,6 @@ internal class Repository {
} }
suspend fun getLastModified(): Long { suspend fun getLastModified(): Long {
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", " --- 3 ----")
return store.getLastModified() return store.getLastModified()
} }
@@ -45,37 +58,84 @@ internal class Repository {
data += Reason().also { data += Reason().also {
it.id = "1" it.id = "1"
it.reason = "变道有干扰" it.reason = "变道有干扰"
it.channel = "被动"
} }
data += Reason().also { data += Reason().also {
it.id = "2" it.id = "2"
it.reason = "遇红绿灯未停车" it.reason = "遇红绿灯未停车"
it.channel = "被动"
} }
data += Reason().also { data += Reason().also {
it.id = "3" it.id = "3"
it.reason = "遇障碍物未停车" it.reason = "遇障碍物未停车"
it.channel = "被动"
} }
data += Reason().also { data += Reason().also {
it.id = "4" it.id = "4"
it.reason = "无法绕行" it.reason = "无法绕行"
it.channel = "被动"
} }
data += Reason().also { data += Reason().also {
it.id = "5" it.id = "5"
it.reason = "画龙" it.reason = "画龙"
it.channel = "被动"
} }
data += Reason().also { data += Reason().also {
it.id = "6" it.id = "6"
it.reason = "转弯过于靠近路侧" it.reason = "转弯过于靠近路侧"
it.channel = "被动"
} }
data += Reason().also { data += Reason().also {
it.id = "7" it.id = "7"
it.reason = "无故退出自动驾驶" it.reason = "无故退出自动驾驶"
it.channel = "被动"
} }
data += Reason().also { data += Reason().also {
it.id = "8" it.id = "8"
it.reason = "其它" it.reason = "其它"
it.channel = "被动"
} }
} else { } else {
TODO() data += Reason().also {
it.id = "1"
it.reason = "定位异常"
it.channel = "主动"
}
data += Reason().also {
it.id = "2"
it.reason = "画龙"
it.channel = "主动"
}
data += Reason().also {
it.id = "3"
it.reason = "红绿灯不识别"
it.channel = "主动"
}
data += Reason().also {
it.id = "4"
it.reason = "地图异常"
it.channel = "主动"
}
data += Reason().also {
it.id = "5"
it.reason = "感知异常"
it.channel = "主动"
}
data += Reason().also {
it.id = "6"
it.reason = "业务异常"
it.channel = "主动"
}
data += Reason().also {
it.id = "7"
it.reason = "显示异常"
it.channel = "主动"
}
data += Reason().also {
it.id = "8"
it.reason = "其它"
it.channel = "主动"
}
} }
return data return data
} }

View File

@@ -5,28 +5,37 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.network.MoGoRetrofitFactory import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.BadCaseApi import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.BadCaseApi
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.BadCaseResponse
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.UploadResult import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.UploadResult
import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseHost import com.zhjt.mogo_core_function_devatools.badcase.consts.BadCaseHost
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.BadCaseResponse.Reason
import kotlinx.coroutines.withContext
import kotlin.coroutines.coroutineContext
internal class BadCaseNetModel { internal class BadCaseNetModel {
suspend fun get(): BadCaseResponse? = try { suspend fun get(channel: String?, result: MutableList<Reason>, pageNo: Int) {
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "-- load cases from net -- 1 --") try {
MoGoRetrofitFactory MoGoRetrofitFactory
.getInstance(BadCaseHost.getHost()) .getInstance(BadCaseHost.getHost())
.create(BadCaseApi::class.java) .create(BadCaseApi::class.java)
.get() .get(channel ?: "", pageNo)
.takeIf { .takeIf {
val body = it.body() val body = it.body()
it.isSuccessful && body != null && (body.code == 0 || body.code == 200) it.isSuccessful && body != null && (body.code == 0 || body.code == 200)
} }
?.body()?.also { ?.body()?.also {
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "-- load cases from net -- 2 --") val data = it.data
} if (data == null || it.total <= result.size) {
} catch (t: Throwable) { return@also
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "-- load cases from net -- 3 --") }
null result += data
withContext(coroutineContext) {
get(channel, result, pageNo + 1)
}
}
} catch (t: Throwable) {
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "-- load cases from net error: $t")
}
} }
suspend fun upload(map: Map<String, String>): UploadResult? = try { suspend fun upload(map: Map<String, String>): UploadResult? = try {

View File

@@ -3,10 +3,7 @@ package com.zhjt.mogo_core_function_devatools.badcase.repository.net.api
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.BadCaseResponse import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.BadCaseResponse
import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.UploadResult import com.zhjt.mogo_core_function_devatools.badcase.repository.net.api.entity.UploadResult
import retrofit2.Response import retrofit2.Response
import retrofit2.http.FieldMap import retrofit2.http.*
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.POST
internal interface BadCaseApi { internal interface BadCaseApi {
@@ -15,5 +12,5 @@ internal interface BadCaseApi {
suspend fun post(@FieldMap map: Map<String, String>): Response<UploadResult> suspend fun post(@FieldMap map: Map<String, String>): Response<UploadResult>
@GET("/yycp-vehicle-management-service/tool/badcase/reasons") @GET("/yycp-vehicle-management-service/tool/badcase/reasons")
suspend fun get(): Response<BadCaseResponse> suspend fun get(@Query("channel", encoded = true) channel: String, @Query("pageNo") pageNo: Int): Response<BadCaseResponse>
} }

View File

@@ -8,16 +8,13 @@ internal class BadCaseResponse {
var code: Int = -1 var code: Int = -1
var data: List<Reason>? = null var data: List<Reason>? = null
var msg: String? = null var msg: String? = null
var success: Boolean = false
var total: Int = -1 var total: Int = -1
@Expose(serialize = false, deserialize = false)
var isBuildIn: Boolean = false
@Keep @Keep
class Reason { class Reason {
var id: String? = null var id: String? = null
var reason: String? = null var reason: String? = null
var channel: String? = null
/** /**
* 业务字段,不参与序列化和反序列化 * 业务字段,不参与序列化和反序列化
@@ -25,21 +22,8 @@ internal class BadCaseResponse {
@Expose(deserialize = false, serialize = false) @Expose(deserialize = false, serialize = false)
var isChecked: Boolean = false var isChecked: Boolean = false
override fun toString(): String {
override fun equals(other: Any?): Boolean { return "Reason(id=$id, reason=$reason, channel=$channel, isChecked=$isChecked)"
if (javaClass != other?.javaClass) return false
other as Reason
if (id != other.id) return false
if (reason != other.reason) return false
if (isChecked != other.isChecked) return false
return true
}
override fun hashCode(): Int {
var result = id?.hashCode() ?: 0
result = 31 * result + (reason?.hashCode() ?: 0)
result = 31 * result + isChecked.hashCode()
return result
} }
} }
} }

View File

@@ -28,7 +28,6 @@ internal object BadCaseStore {
get() = BadCauses.getDefaultInstance() get() = BadCauses.getDefaultInstance()
override suspend fun readFrom(input: InputStream): BadCauses = suspendCancellableCoroutine { override suspend fun readFrom(input: InputStream): BadCauses = suspendCancellableCoroutine {
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "--- readFrom ---")
it.invokeOnCancellation { it.invokeOnCancellation {
Thread.currentThread().interrupt() Thread.currentThread().interrupt()
} }
@@ -65,6 +64,7 @@ internal object BadCaseStore {
data += Cause.newBuilder().let { data += Cause.newBuilder().let {
it.id = itx.id it.id = itx.id
it.reason = itx.reason it.reason = itx.reason
it.channel = itx.channel
it.build() it.build()
} }
} }
@@ -78,14 +78,12 @@ internal object BadCaseStore {
} }
suspend fun updateLastModified(timestamp: Long): BadCauses { suspend fun updateLastModified(timestamp: Long): BadCauses {
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", "--- updateLastModified ---")
return store.updateData { itx -> return store.updateData { itx ->
itx.toBuilder().setLastModified(timestamp).build() itx.toBuilder().setLastModified(timestamp).build()
} }
} }
suspend fun getLastModified(): Long { suspend fun getLastModified(): Long {
CallerLogger.d("$M_DEVA${BadCaseManager.TAG}", " --- 4 ----")
return store return store
.data .data
.catch { .catch {
@@ -107,6 +105,7 @@ internal object BadCaseStore {
Reason().also { itx -> Reason().also { itx ->
itx.id = it.id itx.id = it.id
itx.reason = it.reason itx.reason = it.reason
itx.channel = it.channel
} }
}?.fold(mutableListOf()) { acc, reason -> }?.fold(mutableListOf()) { acc, reason ->
acc += reason acc += reason

View File

@@ -3,6 +3,7 @@ package com.zhjt.mogo_core_function_devatools.feedback
import android.content.Context import android.content.Context
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.ViewGroup
import android.view.WindowManager import android.view.WindowManager
import android.widget.TextView import android.widget.TextView
import com.mogo.cloud.passport.MoGoAiCloudClientConfig import com.mogo.cloud.passport.MoGoAiCloudClientConfig
@@ -11,10 +12,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotManager
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.utilcode.kotlin.onDetach import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.kotlin.safeCancel
import com.mogo.eagle.core.utilcode.kotlin.scope
import com.mogo.eagle.core.utilcode.kotlin.toast
import com.mogo.eagle.core.utilcode.mogo.toast.TipToast import com.mogo.eagle.core.utilcode.mogo.toast.TipToast
import com.mogo.eagle.core.utilcode.util.ThreadUtils import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.zhjt.mogo_core_function_devatools.R import com.zhjt.mogo_core_function_devatools.R
@@ -47,7 +45,7 @@ internal object FeedbackManager {
fun showFeedbackWindow(ctx: Context) { fun showFeedbackWindow(ctx: Context) {
CallerHmiManager.showFloatWindow("FeedbackWindow", FeedBackView(ctx).also { itx -> CallerHmiManager.showFloatWindow("Feedback", FeedBackView(ctx).also { itx ->
itx.registerCallback(object : IFeedbackCallback { itx.registerCallback(object : IFeedbackCallback {
override fun onClose() { override fun onClose() {
hideFloat?.invoke() hideFloat?.invoke()
@@ -130,7 +128,10 @@ internal object FeedbackManager {
} }
} }
}) })
}, WindowManager.LayoutParams().also { it.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN }).also { hideFloat = it } }, WindowManager.LayoutParams().also {
it.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN
}
).also { hideFloat = it }
} }
private fun startRecordLog(record: AutoPilotRecord) { private fun startRecordLog(record: AutoPilotRecord) {

View File

@@ -47,7 +47,7 @@ internal class FeedBackView : ConstraintLayout {
} }
} }
} }
layoutParams = ViewGroup.LayoutParams(960.PX, 1528.PX) layoutParams = ViewGroup.LayoutParams(960.PX, 1600.PX)
close.onClick { close.onClick {
cb?.onClose() cb?.onClose()
} }

View File

@@ -108,7 +108,7 @@ internal class BadCaseFBViewHolder(cb: IFeedbackCallback?, parent: ViewGroup): F
view.onClick { view.onClick {
cb?.onBadCaseItemClicked(itx) cb?.onBadCaseItemClicked(itx)
} }
view.layoutParams = FlexboxLayout.LayoutParams(FlexboxLayout.LayoutParams.MATCH_PARENT, FlexboxLayout.LayoutParams.WRAP_CONTENT).also { view.layoutParams = FlexboxLayout.LayoutParams(FlexboxLayout.LayoutParams.WRAP_CONTENT, FlexboxLayout.LayoutParams.WRAP_CONTENT).also {
it.flexBasisPercent = 0.5f it.flexBasisPercent = 0.5f
} }
addView(view) addView(view)

View File

@@ -14,6 +14,7 @@ message BadCauses {
message Cause { message Cause {
string id = 1; string id = 1;
string reason = 2; string reason = 2;
string channel = 3;
} }

View File

@@ -13,8 +13,7 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent" />
android:layout_marginBottom="120px"/>
<ImageView <ImageView
android:id="@+id/close" android:id="@+id/close"

View File

@@ -3,6 +3,7 @@ package com.mogo.eagle.core.function.hmi.notification.anim
import android.animation.Animator import android.animation.Animator
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.graphics.Rect import android.graphics.Rect
import android.util.Log
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
import com.mogo.eagle.core.data.enums.SidePattern import com.mogo.eagle.core.data.enums.SidePattern
@@ -49,7 +50,9 @@ open class DefaultAnimator : OnFloatAnimator {
if (triple.third) params.x = value else params.y = value if (triple.third) params.x = value else params.y = value
// 动画执行过程中页面关闭,出现异常 // 动画执行过程中页面关闭,出现异常
windowManager.updateViewLayout(view, params) windowManager.updateViewLayout(view, params)
Log.d("XXX", "update ---> ${it.animatedValue}, ${it.animatedFraction}, $value")
} catch (e: Exception) { } catch (e: Exception) {
Log.d("XXX", "exception ---> $e")
cancel() cancel()
} }
} }

View File

@@ -242,7 +242,7 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
.setAnimator(object : DefaultAnimator() { .setAnimator(object : DefaultAnimator() {
override fun enterAnim( override fun enterAnim(
view: View, view: View,
params: WindowManager.LayoutParams, params:LayoutParams,
windowManager: WindowManager, windowManager: WindowManager,
sidePattern: SidePattern sidePattern: SidePattern
): Animator? = ): Animator? =

View File

@@ -255,8 +255,12 @@ private class GestureConflictFixer(private val ids: List<Int>) : RecyclerView.On
private fun computeIntercepted(x: Int, y: Int, rv: RecyclerView, ids: List<Int>): Boolean { private fun computeIntercepted(x: Int, y: Int, rv: RecyclerView, ids: List<Int>): Boolean {
return ids.takeIf { it.isNotEmpty() }?.find { return ids.takeIf { it.isNotEmpty() }?.find {
val out = Rect() val out = Rect()
rv.findViewById<View>(it).getGlobalVisibleRect(out) rv.findViewById<View>(it)?.getGlobalVisibleRect(out)
out.contains(x, y) if (!out.isEmpty) {
out.contains(x, y)
} else {
false
}
}?.let { it != View.NO_ID } ?: false }?.let { it != View.NO_ID } ?: false
} }