DoggyZhang 2 dias atrás
pai
commit
6d54704794

+ 0 - 1
app/build.gradle

@@ -514,7 +514,6 @@ dependencies {
     api libs.tencent.timpush.fcm
 
     api libs.tencent.atomic.x
-    implementation project(":atomic_x")
 
 //    debugApi "com.tuzhenlei:crashhandler:1.0.1"
 //    debugApi 'cat.ereza:customactivityoncrash:2.3.0'

+ 111 - 326
app/src/main/java/com/adealink/weparty/commonui/toast/ToastCompat.kt

@@ -1,367 +1,152 @@
 package com.adealink.weparty.commonui.toast
 
 import android.annotation.SuppressLint
-import android.annotation.TargetApi
-import android.app.Activity
-import android.app.AppOpsManager
-import android.app.NotificationManager
 import android.content.Context
-import android.content.res.Configuration
-import android.graphics.PixelFormat
-import android.graphics.Rect
-import android.os.Build
 import android.os.Handler
-import android.os.Message
-import android.util.Log
+import android.os.Looper
 import android.view.Gravity
-import android.view.WindowManager
-import android.widget.FrameLayout
+import android.view.LayoutInflater
+import android.view.View
 import android.widget.Toast
-import com.adealink.frame.util.ActivityLifecycleCallbacksExt
-import com.adealink.frame.util.AppUtil
-import com.adealink.frame.util.DisplayUtil
-import com.adealink.frame.util.isMIUI
-import com.adealink.frame.util.runOnUiThread
-import java.lang.reflect.Field
-import java.lang.reflect.InvocationTargetException
-import java.lang.reflect.Modifier
+import androidx.annotation.DrawableRes
+import androidx.appcompat.widget.AppCompatImageView
+import androidx.appcompat.widget.AppCompatTextView
+import com.adealink.weparty.R
+import com.adealink.weparty.commonui.ext.dp
+import java.lang.ref.WeakReference
 
-object ToastCompat {
-
-    private const val TAG = "ToastCompat"
-
-    private const val LONG_DELAY = 3500
-    private const val SHORT_DELAY = 2000 // 2 seconds
-
-    private const val UNKNOWN = -1
-    private const val DISABLE = 0
-    private const val ENABLE = 1
-
-    private const val CHECK_OP_NO_THROW = "checkOpNoThrow"
-    private const val OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"
-
-    private var sToastEnable = UNKNOWN
-    private var sUseView = false
-
-    init {
-        AppUtil.registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacksExt {
+private const val ATOMIC_EVENT_ID = 100011
+private const val FRAMEWORK_NAME = "AtomicXCore"
 
-            override fun onEnterBackGround() {
-                sToastEnable = UNKNOWN
-            }
+object ToastCompat {
 
-        })
+    enum class Style {
+        TEXT,
+        INFO,
+        HELP,
+        LOADING,
+        SUCCESS,
+        WARNING,
+        ERROR
     }
 
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
-    fun show(toast: Toast) {
-        // API 30 之后纯 Text 的 Toast 中的 View 为空, 直接调用系统的方法(虽然应该是没有用的)
-        if (toast.view == null) {
-            toast.show()
-            return
-        }
-        val context: Context = AppUtil.appContext
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1 && !sUseView && !isMIUI()) {
-            val windowManager: WindowManager? =
-                AppUtil.getSystemService<WindowManager>(Context.WINDOW_SERVICE)
-            // defined that sets up the layout params appropriately.
-            val params = WindowManager.LayoutParams()
-            params.height = WindowManager.LayoutParams.WRAP_CONTENT
-            params.width = WindowManager.LayoutParams.WRAP_CONTENT
-            params.format = PixelFormat.TRANSLUCENT
-            val animation = context.resources.getIdentifier("Animation_Toast", "style", "android")
-            if (animation > 0) {
-                params.windowAnimations = animation
-            }
-            params.type = WindowManager.LayoutParams.TYPE_TOAST
-            params.title = "Toast"
-            params.packageName = context.packageName
-            params.flags =
-                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-            params.horizontalMargin = toast.horizontalMargin
-            params.verticalMargin = toast.verticalMargin
-            val config = context.resources.configuration
-            val gravity = Gravity.getAbsoluteGravity(toast.gravity, config.layoutDirection)
-            params.gravity = gravity
-            if (gravity and Gravity.HORIZONTAL_GRAVITY_MASK == Gravity.FILL_HORIZONTAL) {
-                params.horizontalWeight = 1.0f
-            }
-            if (gravity and Gravity.VERTICAL_GRAVITY_MASK == Gravity.FILL_VERTICAL) {
-                params.verticalWeight = 1.0f
-            }
-            params.x = toast.xOffset
-            params.y = toast.yOffset
-            try {
-                windowManager?.addView(toast.view, params)
-            } catch (e: WindowManager.BadTokenException) {
-                e.printStackTrace()
-                sUseView = true
-            }
-            if (!sUseView) {
-                runOnUiThread({ windowManager?.removeView(toast.view) },
-                    (if (toast.duration == Toast.LENGTH_LONG) LONG_DELAY else SHORT_DELAY).toLong())
-                return
-            }
-        }
-        val activity: Activity? = AppUtil.currentActivity
-        if (activity == null) {
-            Log.e(TAG, "activity is null")
-        } else {
-            val root = activity.window.decorView
-            val rect = Rect()
-            root.getWindowVisibleDisplayFrame(rect)
-            val statusBarHeight = rect.top
-            if (root is FrameLayout) {
-                val layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
-                    FrameLayout.LayoutParams.WRAP_CONTENT,
-                    Gravity.CENTER_HORIZONTAL or toast.gravity)
-                val orientation: Int = DisplayUtil.getOrientation()
-                //虚拟栏存在的情况下居中调整
-                if (orientation == Configuration.ORIENTATION_PORTRAIT) {
-                    val navHeight: Int = DisplayUtil.getScreenRealHeight(activity) - rect.bottom
-                    when {
-                        toast.gravity and Gravity.BOTTOM == Gravity.BOTTOM -> {
-                            layoutParams.bottomMargin = toast.yOffset + navHeight
-                        }
-                        toast.gravity and Gravity.TOP == Gravity.TOP -> {
-                            layoutParams.topMargin = toast.yOffset + statusBarHeight
-                        }
-                        toast.gravity and Gravity.CENTER == Gravity.CENTER -> {
-                            layoutParams.topMargin = toast.yOffset
-                        }
-                        else -> {
-                            layoutParams.bottomMargin = toast.yOffset + navHeight
-                        }
-                    }
-                    when {
-                        toast.gravity and Gravity.START == Gravity.START -> {
-                            layoutParams.marginStart = toast.xOffset
-                        }
-                        toast.gravity and Gravity.END == Gravity.END -> {
-                            layoutParams.marginEnd = toast.xOffset
-                        }
-                        else -> {
-                            layoutParams.leftMargin = toast.xOffset
-                        }
-                    }
-                } else {
-                    val config = context.resources.configuration
-                    val gravity = Gravity.getAbsoluteGravity(toast.gravity, config.layoutDirection)
-                    val navPositionRight = rect.left == 0
-                    val navHeight =
-                        if (navPositionRight) DisplayUtil.getScreenRealWidth(activity) - rect.right else rect.left
-                    when {
-                        gravity and Gravity.BOTTOM == Gravity.BOTTOM -> {
-                            layoutParams.bottomMargin = toast.yOffset
-                        }
-                        gravity and Gravity.TOP == Gravity.TOP -> {
-                            layoutParams.topMargin = toast.yOffset + statusBarHeight
-                        }
-                        else -> {
-                            layoutParams.bottomMargin = toast.yOffset
-                        }
-                    }
-                    when {
-                        gravity and Gravity.LEFT == Gravity.LEFT -> {
-                            layoutParams.leftMargin =
-                                toast.xOffset + if (navPositionRight) 0 else navHeight
-                        }
-                        gravity and Gravity.RIGHT == Gravity.RIGHT -> {
-                            layoutParams.rightMargin =
-                                toast.xOffset + if (navPositionRight) navHeight else 0
-                        }
-                        else -> {
-                            layoutParams.leftMargin =
-                                toast.xOffset + if (navPositionRight) -navHeight / 2 else navHeight / 2
-                        }
-                    }
-                }
-                root.addView(toast.view, layoutParams)
-                runOnUiThread({ root.removeView(toast.view) },
-                    (if (toast.duration == Toast.LENGTH_LONG) LONG_DELAY else SHORT_DELAY).toLong())
-            }
-        }
+    enum class Position {
+        TOP,
+        CENTER,
+        BOTTOM
     }
 
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
-    fun show(content: CharSequence?, duration: Int) {
-        show(Toast.makeText(AppUtil.appContext, content, duration))
-    }
+    enum class Duration(val value: Int) {
+        SHORT(Toast.LENGTH_SHORT),
+        LONG(Toast.LENGTH_LONG);
 
-    fun isToastEnabled(): Boolean {
-        if (sToastEnable == DISABLE) {
-            return false
-        }
-        if (sToastEnable == ENABLE) {
-            return true
-        }
-        val context: Context = AppUtil.appContext
-        return when {
-            Build.VERSION.SDK_INT >= 24 -> {
-                val notificationManager: NotificationManager =
-                    AppUtil.getSystemService<NotificationManager>(Context.NOTIFICATION_SERVICE)
-                        ?: return false
-                recordToastEnable(notificationManager.areNotificationsEnabled())
-            }
-            Build.VERSION.SDK_INT >= 19 -> {
-                val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
-                val appInfo = context.applicationInfo
-                val pkg = context.applicationContext.packageName
-                val uid = appInfo.uid
-                try {
-                    val appOpsClass = Class.forName(AppOpsManager::class.java.name)
-                    val checkOpNoThrowMethod =
-                        appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE,
-                            String::class.java)
-                    val opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION)
-                    val value = opPostNotificationValue[Int::class.java] as Int
-                    recordToastEnable(checkOpNoThrowMethod.invoke(appOps,
-                        value,
-                        uid,
-                        pkg) as Int == AppOpsManager.MODE_ALLOWED)
-                } catch (e: ClassNotFoundException) {
-                    recordToastEnable(true)
-                } catch (e: NoSuchMethodException) {
-                    recordToastEnable(true)
-                } catch (e: NoSuchFieldException) {
-                    recordToastEnable(true)
-                } catch (e: InvocationTargetException) {
-                    recordToastEnable(true)
-                } catch (e: IllegalAccessException) {
-                    recordToastEnable(true)
-                } catch (e: RuntimeException) {
-                    recordToastEnable(true)
-                }
-            }
-            else -> {
-                recordToastEnable(true)
+        companion object {
+            @JvmStatic
+            fun map(duration: Int): Duration {
+                return entries.find { it.value == duration } ?: SHORT
             }
         }
     }
 
-    private fun recordToastEnable(enable: Boolean): Boolean {
-        sToastEnable = if (enable) ENABLE else DISABLE
-        return enable
-    }
-
-    @SuppressLint("ShowToast")
-    fun makeText(context: Context?, text: CharSequence?, duration: Int): Toast {
-        val toast = Toast.makeText(context, text, duration)
-        if (Build.VERSION.SDK_INT == 25 || Build.VERSION.SDK_INT == 19) {
-            tryToHack(toast)
+    private var toastRef: WeakReference<Toast>? = null
+    private var layoutRef: WeakReference<View>? = null
+
+    private val mainHandler = Handler(Looper.getMainLooper())
+    private var pendingTask: Runnable? = null
+
+    fun show(
+        context: Context,
+        text: String,
+        style: Style = Style.TEXT,
+        position: Position = Position.CENTER,
+        @DrawableRes customIcon: Int? = null,
+        duration: Duration = Duration.SHORT,
+        code: Int? = null,
+        extensionInfo: Map<String, Any>? = null
+    ) {
+        if (text.isBlank()) return
+
+        pendingTask?.let {
+            mainHandler.removeCallbacks(it)
+            pendingTask = null
         }
-        return toast
-    }
 
-    @SuppressLint("ShowToast")
-    fun makeText(context: Context?, resId: Int, duration: Int): Toast {
-        val toast = Toast.makeText(context, resId, duration)
-        if (Build.VERSION.SDK_INT == 25 || Build.VERSION.SDK_INT == 19) {
-            tryToHack(toast)
-        }
-        return toast
-    }
+        val appContext = context.applicationContext
 
-    fun tryToHack(toast: Toast) {
-        try {
-            val mTN = getFieldValue(toast, "mTN")
-            if (mTN != null) {
-                var isSuccess = false
-                val rawShowRunnable = getFieldValue(mTN, "mShow")
-                if (rawShowRunnable is Runnable) {
-                    isSuccess = setFieldValue(mTN, "mShow", InternalRunnable(rawShowRunnable))
-                }
-                if (!isSuccess) {
-                    val rawHandler = getFieldValue(mTN, "mHandler")
-                    if (rawHandler is Handler) {
-                        isSuccess = setFieldValue(rawHandler, "mCallback", InternalHandlerCallback(
-                            rawHandler))
-                    }
-                }
-                if (!isSuccess) {
-                    Log.e("ToastCompat", "tryToHack error.")
+        val task = object : Runnable {
+            override fun run() {
+                executeRealShow(appContext, text, style, position, customIcon, duration)
+                if (pendingTask === this) {
+                    pendingTask = null
                 }
             }
-        } catch (var5: Throwable) {
-            var5.printStackTrace()
         }
+        pendingTask = task
+        mainHandler.postDelayed(task, 50)
     }
 
-    private fun setFieldValue(`object`: Any, fieldName: String, newFieldValue: Any): Boolean {
-        val field = getDeclaredField(`object`, fieldName)
-        if (field != null) {
-            try {
-                val accessFlags = field.modifiers
-                if (Modifier.isFinal(accessFlags)) {
-                    val modifiersField = Field::class.java.getDeclaredField("accessFlags")
-                    modifiersField.isAccessible = true
-                    modifiersField.setInt(field, field.modifiers and -17)
-                }
-                if (!field.isAccessible) {
-                    field.isAccessible = true
-                }
-                field[`object`] = newFieldValue
-                return true
-            } catch (var6: Exception) {
-                var6.printStackTrace()
-            }
-        }
-        return false
-    }
+    private fun executeRealShow(
+        appContext: Context,
+        text: String,
+        style: Style,
+        position: Position,
+        @DrawableRes customIcon: Int?,
+        duration: Duration,
+    ) {
 
-    private fun getFieldValue(obj: Any, fieldName: String): Any? {
-        val field = getDeclaredField(obj, fieldName)
-        return getFieldValue(obj, field)
-    }
+        var toast = toastRef?.get()
+        var layout = layoutRef?.get()
 
-    private fun getFieldValue(obj: Any, field: Field?): Any? {
-        if (field != null) {
-            try {
-                if (!field.isAccessible) {
-                    field.isAccessible = true
-                }
-                return field[obj]
-            } catch (var3: Exception) {
-                var3.printStackTrace()
-            }
+        if (toast == null || layout == null) {
+            layout = LayoutInflater.from(appContext).inflate(R.layout.layout_compat_toast, null)
+            toast = Toast(appContext)
+
+            @Suppress("DEPRECATION")
+            toast.view = layout
+
+            layoutRef = WeakReference(layout)
+            toastRef = WeakReference(toast)
         }
-        return null
-    }
 
-    private fun getDeclaredField(obj: Any, fieldName: String): Field? {
-        var superClass: Class<*> = obj.javaClass
-        while (superClass != Any::class.java) {
-            superClass = try {
-                return superClass.getDeclaredField(fieldName)
-            } catch (var4: NoSuchFieldException) {
-                superClass.superclass
+        applyDesignTokens(layout, text, style, customIcon)
+
+        toast.apply {
+            this.duration = duration.value
+            val gravity = when (position) {
+                Position.TOP -> Gravity.TOP or Gravity.CENTER_HORIZONTAL
+                Position.CENTER -> Gravity.CENTER
+                Position.BOTTOM -> Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
             }
+            setGravity(gravity, 0, if (position == Position.CENTER) 0 else 24.dp())
+            show()
         }
-        return null
     }
 
-    private class InternalHandlerCallback(private val mHandler: Handler) :
-        Handler.Callback {
-        override fun handleMessage(msg: Message): Boolean {
-            try {
-                mHandler.handleMessage(msg)
-            } catch (var3: Throwable) {
-                Log.e("ToastCompat", "catch $var3")
-                var3.printStackTrace()
-            }
-            return true
+    @SuppressLint("SetTextI18n")
+    private fun applyDesignTokens(
+        container: View,
+        text: String,
+        style: Style,
+        @DrawableRes customIcon: Int?,
+    ) {
+        val iconView = container.findViewById<AppCompatImageView>(R.id.iv_toast)
+        val textView = container.findViewById<AppCompatTextView>(R.id.tv_toast)
+
+        textView.text = text
+        val iconRes = customIcon ?: resolveIconRes(style)
+        if (iconRes != null) {
+            iconView.visibility = View.VISIBLE
+            iconView.setImageResource(iconRes)
+        } else {
+            iconView.visibility = View.GONE
         }
     }
 
-    private class InternalRunnable(private val mRunnable: Runnable) : Runnable {
-        override fun run() {
-            try {
-                mRunnable.run()
-            } catch (var2: Throwable) {
-                Log.e("ToastCompat", "catch $var2")
-                var2.printStackTrace()
-            }
+    @DrawableRes
+    private fun resolveIconRes(style: Style): Int? {
+        return when (style) {
+            Style.WARNING -> R.drawable.common_toast_warming_ic
+            else -> null
         }
     }
-
 }

+ 10 - 11
app/src/main/java/com/adealink/weparty/commonui/toast/util/ToastUtil.kt

@@ -11,21 +11,20 @@ import com.adealink.frame.util.runOnUiThread
 import com.adealink.weparty.BuildConfig
 import com.adealink.weparty.R
 import com.adealink.weparty.commonui.toast.ToastCompat
-import io.trtc.tuikit.atomicx.widget.basicwidget.toast.AtomicToast
-import io.trtc.tuikit.atomicx.widget.basicwidget.toast.AtomicToast.Duration
 
 fun showToast(text: CharSequence) {
     showToast(text, Toast.LENGTH_SHORT)
 }
 
-fun showToast(text: CharSequence, duration: Int) {
+fun showToast(text: CharSequence, duration: Int = Toast.LENGTH_SHORT, style: ToastCompat.Style = ToastCompat.Style.TEXT) {
     runOnUiThread {
-        AtomicToast.show(AppUtil.appContext, text = text.toString(),  position = AtomicToast.Position.CENTER, duration = Duration.map(duration))
-//        if (ToastCompat.isToastEnabled()) {
-//            ToastCompat.makeText(AppUtil.appContext, text, duration).show()
-//        } else {
-//            ToastCompat.show(text, duration)
-//        }
+        ToastCompat.show(
+            AppUtil.appContext,
+            text = text.toString(),
+            position = ToastCompat.Position.CENTER,
+            duration = ToastCompat.Duration.map(duration),
+            style = style
+        )
     }
 }
 
@@ -33,9 +32,9 @@ fun showToast(@StringRes resId: Int) {
     showToast(resId, Toast.LENGTH_SHORT)
 }
 
-fun showToast(@StringRes resId: Int, duration: Int) {
+fun showToast(@StringRes resId: Int, duration: Int, style: ToastCompat.Style = ToastCompat.Style.TEXT) {
     runOnUiThread {
-        showToast(getCompatString(resId), duration)
+        showToast(getCompatString(resId), duration = duration, style = style)
     }
 }
 

BIN
app/src/main/res/drawable-xhdpi/common_toast_warming_ic.png


+ 41 - 0
app/src/main/res/layout/layout_compat_toast.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/ll_container"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:background="@drawable/common_toast_bg"
+    android:minHeight="40dp"
+    android:orientation="horizontal"
+    android:paddingHorizontal="20dp"
+    android:paddingVertical="12dp">
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/iv_toast"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:contentDescription="@null"
+        android:scaleType="fitCenter"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:srcCompat="@drawable/common_toast_warming_ic" />
+
+    <androidx.appcompat.widget.AppCompatTextView
+        android:id="@+id/tv_toast"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="4dp"
+        android:ellipsize="end"
+        android:includeFontPadding="false"
+        android:maxWidth="320dp"
+        android:maxLines="6"
+        android:textColor="@color/white"
+        android:textSize="14sp"
+        app:layout_constrainedWidth="true"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/iv_toast" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>

BIN
frame/atomic_x/src/main/res-callview/raw/phone_dialing.mp3


BIN
frame/atomic_x/src/main/res-callview/raw/phone_ringing.mp3


+ 3 - 3
module/call/src/main/java/com/tencent/qcloud/tuikit/tuicallkit/manager/feature/CallingBellFeature.kt

@@ -11,7 +11,6 @@ import android.os.HandlerThread
 import android.text.TextUtils
 import androidx.core.content.ContextCompat
 import com.adealink.frame.log.Log
-import com.adealink.weparty.call.R
 import com.adealink.weparty.call.util.PermissionRequest
 import com.tencent.cloud.tuikit.engine.call.TUICallEngine
 import com.tencent.liteav.audio.TXAudioEffectManager.AudioMusicParam
@@ -28,6 +27,7 @@ import kotlinx.coroutines.MainScope
 import kotlinx.coroutines.launch
 import java.io.File
 import java.io.FileOutputStream
+import io.trtc.tuikit.atomicx.R as ATOMIC_X_R
 
 class CallingBellFeature(context: Context) {
     private val scope = MainScope()
@@ -94,7 +94,7 @@ class CallingBellFeature(context: Context) {
         }
         val path = SPUtils.getInstance(PROFILE_TUICALLKIT).getString(PROFILE_CALL_BELL, "")
         if (TextUtils.isEmpty(path)) {
-            start("", R.raw.phone_ringing)
+            start("", ATOMIC_X_R.raw.phone_ringing)
         } else {
             start(path, -1)
         }
@@ -115,7 +115,7 @@ class CallingBellFeature(context: Context) {
 
     private fun startDialingMusic() {
         if (TextUtils.isEmpty(dialPath)) {
-            dialPath = getBellPath(context, R.raw.phone_dialing, "phone_dialing.mp3")
+            dialPath = getBellPath(context, ATOMIC_X_R.raw.phone_dialing, "phone_dialing.mp3")
         }
         if (TextUtils.isEmpty(dialPath)) {
             Log.e(TAG, "startDialingMusic failed: dialPath is null or empty")

BIN
module/call/src/main/res/raw/phone_dialing.mp3


BIN
module/call/src/main/res/raw/phone_ringing.mp3


+ 16 - 3
module/room/src/main/java/com/adealink/weparty/room/applymic/viewmodel/ApplyMicViewModel.kt

@@ -15,8 +15,10 @@ import com.adealink.weparty.module.profile.ProfileModule
 import com.adealink.weparty.room.applymic.ApplyMicStore
 import com.adealink.weparty.room.applymic.data.APPLY_MIC_LIST_TYPE_ALL
 import com.adealink.weparty.room.applymic.data.ApplyMicItemData
+import com.adealink.weparty.room.data.APPLY_MIC_ONLY_HOST_ERROR
 import com.adealink.weparty.room.data.AcceptApplyMicReq
 import com.adealink.weparty.room.data.ApplyMicListReq
+import com.adealink.weparty.room.data.ApplyMicOnlyHostError
 import com.adealink.weparty.room.data.ApplyMicReq
 import com.adealink.weparty.room.data.CancelApplyMicReq
 import com.adealink.weparty.room.data.ClearApplyMicListReq
@@ -157,10 +159,21 @@ class ApplyMicViewModel : BaseViewModel() {
                     roomId, micIndex
                 )
             )
-            if (rlt.isSuccess) {
-                ApplyMicStore.addApplyRecord(roomId, micIndex)
+            when (rlt) {
+                is Rlt.Failed -> {
+                    if (rlt.error.serverCode == APPLY_MIC_ONLY_HOST_ERROR) {
+                        //申请主持人麦位,需要主持人或房主权限
+                        liveData.send(Rlt.Failed(ApplyMicOnlyHostError()))
+                    } else {
+                        liveData.send(rlt)
+                    }
+                }
+
+                is Rlt.Success -> {
+                    ApplyMicStore.addApplyRecord(roomId, micIndex)
+                    liveData.send(rlt)
+                }
             }
-            liveData.send(rlt)
         }
         return liveData
     }

+ 10 - 1
module/room/src/main/java/com/adealink/weparty/room/data/RoomError.kt

@@ -4,4 +4,13 @@ import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.base.IError
 import com.adealink.weparty.room.R
 
-data class SeatAudioLockError(override val msg: String = getCompatString(R.string.room_err_seat_audio_locked)) : IError()
+
+const val APPLY_MIC_ONLY_HOST_ERROR = 50001
+
+
+data class SeatAudioLockError(override val msg: String = getCompatString(R.string.room_err_seat_audio_locked)) : IError()
+
+data class ApplyMicOnlyHostError(
+    override var serverCode: Int = APPLY_MIC_ONLY_HOST_ERROR,
+    override val msg: String = getCompatString(R.string.room_request_host_mic_fail_for_no_host_permission)
+) : IError()

+ 15 - 2
module/room/src/main/java/com/adealink/weparty/room/micseat/dispatcenter/DispatchCenterSeatsTemplate.kt

@@ -3,13 +3,14 @@ package com.adealink.weparty.room.micseat.dispatcenter
 import android.os.Bundle
 import androidx.fragment.app.activityViewModels
 import androidx.fragment.app.viewModels
-import com.adealink.frame.aab.util.getCompatDrawable
 import com.adealink.frame.aab.util.getCompatString
+import com.adealink.frame.base.Rlt
 import com.adealink.frame.guide.GuideCenter
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.router.Router
 import com.adealink.frame.util.onClick
 import com.adealink.weparty.commonui.dialogfragment.RoomTextActionDialog
+import com.adealink.weparty.commonui.toast.ToastCompat
 import com.adealink.weparty.commonui.toast.util.showFailedToast
 import com.adealink.weparty.commonui.toast.util.showToast
 import com.adealink.weparty.commonui.widget.BottomDialogFragment
@@ -25,6 +26,7 @@ import com.adealink.weparty.room.R
 import com.adealink.weparty.room.applymic.ApplyMicDialog
 import com.adealink.weparty.room.applymic.viewmodel.ApplyMicViewModel
 import com.adealink.weparty.room.chatroom.page.dispatchcenter.DispatchRoomEventViewModel
+import com.adealink.weparty.room.data.ApplyMicOnlyHostError
 import com.adealink.weparty.room.databinding.FragmentSeatsTemplateDispatchCenterBinding
 import com.adealink.weparty.room.guide.RoomGuideType
 import com.adealink.weparty.room.invite.InviteMicDialog
@@ -158,7 +160,18 @@ class DispatchCenterSeatsTemplate :
                 if (seatView.micIndex.index == MIC_HOST) {
                     //申请上主持人麦位
                     applyMicViewModel.applyMic(MIC_HOST).observe(viewLifecycleOwner) { rlt ->
-                        showFailedToast(rlt)
+                        when(rlt){
+                            is Rlt.Failed -> {
+                                if (rlt.error is ApplyMicOnlyHostError) {
+                                    showToast(rlt.error.msg, style = ToastCompat.Style.WARNING)
+                                } else {
+                                    showFailedToast(rlt)
+                                }
+                            }
+                            is Rlt.Success -> {
+                                //Ntd.
+                            }
+                        }
                     }
 //                    if (eventViewModel.isHost()) {
 //