瀏覽代碼

房间最小化

DoggyZhang 3 周之前
父節點
當前提交
b98c442874

+ 2 - 0
app/src/main/java/com/adealink/weparty/commonui/widget/floatview/FloatViewFactory.kt

@@ -7,6 +7,7 @@ import com.adealink.weparty.commonui.widget.floatview.view.BaseFloatView
 import com.adealink.weparty.debug.SysMemoryUsageFloatData
 import com.adealink.weparty.debug.SysMemoryUsageFloatView
 import com.adealink.weparty.module.call.CallModule
+import com.adealink.weparty.module.room.RoomModule
 
 class FloatViewFactory : IFloatViewFactory {
 
@@ -15,6 +16,7 @@ class FloatViewFactory : IFloatViewFactory {
             FloatWindowType.NETWORK_DISCONNECT_TIP -> null//NetworkReconnectFloatView(data as NetworkReconnectFloatData)
             FloatWindowType.MEMORY_USAGE -> SysMemoryUsageFloatView(data as SysMemoryUsageFloatData)
             FloatWindowType.CALL_1V1_CALLING -> CallModule.getCallingFloatView(data)
+            FloatWindowType.MINIMIZE_ROOM -> RoomModule.getMinimizedRoomView(data)
         }
         return floatView as? V
     }

+ 1 - 1
app/src/main/java/com/adealink/weparty/commonui/widget/floatview/data/IFloatData.kt

@@ -3,7 +3,7 @@ package com.adealink.weparty.commonui.widget.floatview.data
 enum class FloatWindowType(val type: String) {
     NETWORK_DISCONNECT_TIP("network_disconnect_tip"),
     MEMORY_USAGE("memory_usage"),
-
+    MINIMIZE_ROOM("minimize_room"),
     CALL_1V1_CALLING("call_1v1_calling"),
 }
 

+ 6 - 0
app/src/main/java/com/adealink/weparty/module/room/IRoomService.kt

@@ -3,11 +3,17 @@ package com.adealink.weparty.module.room
 import com.adealink.frame.aab.IService
 import com.adealink.frame.media.IMediaOperatorGet
 import com.adealink.weparty.commonui.BaseActivity
+import com.adealink.weparty.commonui.widget.floatview.data.IFloatData
+import com.adealink.weparty.commonui.widget.floatview.view.BaseFloatView
 
 interface IRoomService : IService<IRoomService>, IMediaOperatorGet {
 
+    fun init()
+
     fun checkRoomPermission()
 
     fun createRoom(activity: BaseActivity)
 
+    fun getMinimizedRoomView(data: IFloatData): BaseFloatView<out IFloatData>?
+
 }

+ 21 - 1
app/src/main/java/com/adealink/weparty/module/room/RoomModule.kt

@@ -8,6 +8,8 @@ import com.adealink.frame.media.MediaConflictConfig
 import com.adealink.frame.media.MediaInfo
 import com.adealink.weparty.R
 import com.adealink.weparty.commonui.BaseActivity
+import com.adealink.weparty.commonui.widget.floatview.data.IFloatData
+import com.adealink.weparty.commonui.widget.floatview.view.BaseFloatView
 
 object RoomModule : BaseDynamicModule<IRoomService>(IRoomService::class), IRoomService {
 
@@ -25,7 +27,10 @@ object RoomModule : BaseDynamicModule<IRoomService>(IRoomService::class), IRoomS
 
             override fun getMediaOperator(): IMediaOperator {
                 return object : IMediaOperator {
-                    override suspend fun confirmExitConflictMedia(exitMediaInfo: MediaInfo, enterMediaInfo: MediaInfo): Rlt<Any> {
+                    override suspend fun confirmExitConflictMedia(
+                        exitMediaInfo: MediaInfo,
+                        enterMediaInfo: MediaInfo
+                    ): Rlt<Any> {
                         return Rlt.Failed(AABModuleNotInitError())
                     }
 
@@ -57,12 +62,19 @@ object RoomModule : BaseDynamicModule<IRoomService>(IRoomService::class), IRoomS
                 }
             }
 
+            override fun init() {
+            }
+
             override fun checkRoomPermission() {
             }
 
             override fun createRoom(activity: BaseActivity) {
             }
 
+            override fun getMinimizedRoomView(data: IFloatData): BaseFloatView<out IFloatData>? {
+                return null
+            }
+
         }
     }
 
@@ -70,6 +82,10 @@ object RoomModule : BaseDynamicModule<IRoomService>(IRoomService::class), IRoomS
         return getService().getMediaOperator()
     }
 
+    override fun init() {
+        getService().init()
+    }
+
     override fun checkRoomPermission() {
         getService().checkRoomPermission()
     }
@@ -78,4 +94,8 @@ object RoomModule : BaseDynamicModule<IRoomService>(IRoomService::class), IRoomS
         getService().createRoom(activity)
     }
 
+    override fun getMinimizedRoomView(data: IFloatData): BaseFloatView<out IFloatData>? {
+        return getService().getMinimizedRoomView(data)
+    }
+
 }

+ 0 - 5
app/src/main/java/com/adealink/weparty/module/room/listener/IRoomListener.kt

@@ -9,9 +9,4 @@ interface IRoomListener : IListener {
     fun onRoomIn(roomId: Long, flowStateInfo: FlowStateInfo) {}
 
     fun onRoomLeaved(roomId: Long, flowStateInfo: FlowStateInfo) {}
-
-    fun onChannelIn(roomId: Long) {}
-
-    fun onChannelLeave(roomId: Long) {}
-
 }

+ 1 - 0
app/src/main/java/com/adealink/weparty/ui/MainStartUpFragment.kt

@@ -134,6 +134,7 @@ class MainStartUpFragment : BaseFragment() {
         WalletModule.queryAndHandleUnDealPurchases()
 
         OrderModule.queryDiscountInfo()
+        RoomModule.init()
         RoomModule.checkRoomPermission()
         Log.d(TAG, "minorLoad-end, cost:${SystemClock.elapsedRealtime() - startTs}ms")
     }

+ 1 - 0
frame/room/src/main/java/com/adealink/frame/room/data/RoomFlowData.kt

@@ -49,6 +49,7 @@ data class JoinRoomReq(
 
 enum class LeaveRoomReason(val reason: String) {
     INITIATIVE("initiative"),
+    ENTER_OTHER_MEDIA("enter_other_room")
 }
 
 enum class JoinChannelReason(val reason: String) {

+ 2 - 0
module/room/src/main/java/com/adealink/weparty/room/RoomActivity.kt

@@ -18,6 +18,7 @@ import com.adealink.weparty.room.constant.logRoomTime
 import com.adealink.weparty.room.databinding.ActivityRoomBinding
 import com.adealink.weparty.room.interceptor.EnterRoomUriInterceptor
 import com.adealink.weparty.room.listener.IRoomOpListener
+import com.adealink.weparty.room.minimize.manager.minimizeRoomManager
 import com.adealink.weparty.room.sdk.service.roomService
 import com.adealink.weparty.room.viewmodel.RoomFlowViewModel
 import com.adealink.weparty.room.viewmodel.RoomViewModelFactory
@@ -193,6 +194,7 @@ class RoomActivity : BaseActivity(), IRoomOpListener {
     }
 
     private fun handleExitRoom(reason: LeaveRoomReason) {
+        minimizeRoomManager.removeMinimizedRoomView()
         flowViewModel.tryLeaveRoom(reason)
         finish()
     }

+ 19 - 11
module/room/src/main/java/com/adealink/weparty/room/RoomServiceImpl.kt

@@ -2,39 +2,38 @@ package com.adealink.weparty.room
 
 import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.base.Rlt
-import com.adealink.frame.data.collections.ConcurrentList
 import com.adealink.frame.media.IMediaOperator
 import com.adealink.frame.media.MediaConflictConfig
 import com.adealink.frame.media.MediaInfo
+import com.adealink.frame.room.data.LeaveRoomReason
 import com.adealink.frame.spi.RegisterService
 import com.adealink.weparty.commonui.BaseActivity
+import com.adealink.weparty.commonui.widget.floatview.data.IFloatData
 import com.adealink.weparty.media.MediaType
 import com.adealink.weparty.module.room.IRoomService
-import com.adealink.weparty.module.room.listener.IRoomListener
 import com.adealink.weparty.room.create.CreateRoomDialog
 import com.adealink.weparty.room.manager.roomManager
+import com.adealink.weparty.room.minimize.manager.minimizeRoomManager
+import com.adealink.weparty.room.minimize.view.MinimizedRoomFloatData
+import com.adealink.weparty.room.minimize.view.MinimizedRoomFloatView
+import com.adealink.weparty.room.sdk.service.roomService
 
 @RegisterService(IRoomService::class)
 class RoomServiceImpl : IRoomService {
 
-    private val listeners = ConcurrentList<IRoomListener>()
-
-
-    override fun getService(): IRoomService {
-        return this
+    override fun init() {
+        minimizeRoomManager.init()
     }
 
     override fun getMediaOperator(): IMediaOperator {
         return object : IMediaOperator {
 
             override suspend fun isMediaIn(): Boolean {
-                // TODO: zhangfei
-                return false
-//                return roomService.joinController.isRoomJoiningOrJoined()
+                return roomService.joinController.isRoomJoiningOrJoined()
             }
 
             override suspend fun leaveMedia(): Rlt<Any> {
-//                roomService.joinController.tryLeaveRoom(LeaveRoomReason.ENTER_OTHER_MEDIA, true)
+                roomService.joinController.leaveRoom(LeaveRoomReason.ENTER_OTHER_MEDIA, true)
                 return Rlt.Success(Any())
             }
 
@@ -100,4 +99,13 @@ class RoomServiceImpl : IRoomService {
         CreateRoomDialog().show(activity.supportFragmentManager)
     }
 
+    override fun getMinimizedRoomView(data: IFloatData): MinimizedRoomFloatView {
+        return MinimizedRoomFloatView(data as MinimizedRoomFloatData)
+    }
+
+    override fun getService(): IRoomService {
+        return this
+    }
+
+
 }

+ 6 - 0
module/room/src/main/java/com/adealink/weparty/room/minimize/listener/ICloseRoomActionListener.kt

@@ -0,0 +1,6 @@
+package com.adealink.weparty.room.minimize.listener
+
+interface ICloseRoomActionListener {
+    fun onRoomMinimizeClick()
+    fun onRoomCloseClick()
+}

+ 7 - 0
module/room/src/main/java/com/adealink/weparty/room/minimize/manager/IMinimizeRoomManager.kt

@@ -0,0 +1,7 @@
+package com.adealink.weparty.room.minimize.manager
+
+interface IMinimizeRoomManager {
+    fun init()
+    fun addMinimizedRoomView()
+    fun removeMinimizedRoomView()
+}

+ 180 - 0
module/room/src/main/java/com/adealink/weparty/room/minimize/manager/MinimizeRoomManager.kt

@@ -0,0 +1,180 @@
+package com.adealink.weparty.room.minimize.manager
+
+import android.app.Activity
+import com.adealink.frame.base.fastLazy
+import com.adealink.frame.coroutine.dispatcher.Dispatcher
+import com.adealink.frame.log.Log
+import com.adealink.frame.room.data.FlowStateInfo
+import com.adealink.frame.room.data.LeaveRoomReason
+import com.adealink.frame.room.data.RoomState
+import com.adealink.frame.router.Router
+import com.adealink.frame.util.ActivityLifecycleCallbacksExt
+import com.adealink.frame.util.AppUtil
+import com.adealink.frame.util.runOnUiThread
+import com.adealink.weparty.commonui.widget.floatview.FloatViewFactory
+import com.adealink.weparty.commonui.widget.floatview.WindowManagerProxy
+import com.adealink.weparty.commonui.widget.floatview.data.MODE_APPLICATION
+import com.adealink.weparty.module.room.Room
+import com.adealink.weparty.module.room.data.EnterRoomInfo
+import com.adealink.weparty.room.minimize.view.MinimizedRoomFloatData
+import com.adealink.weparty.room.minimize.view.MinimizedRoomFloatView
+import com.adealink.weparty.room.sdk.listener.IJoinListener
+import com.adealink.weparty.room.sdk.service.roomService
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+val minimizeRoomManager: IMinimizeRoomManager by lazy { MinimizeRoomManager() }
+
+class MinimizeRoomManager : IMinimizeRoomManager,
+    ActivityLifecycleCallbacksExt, IJoinListener {
+    private var minimizedRoomFloatView: MinimizedRoomFloatView? = null
+    private val floatViewFactory by fastLazy { FloatViewFactory() }
+
+    val show: Boolean
+        get() {
+            roomService.joinController.joinedRoomInfo ?: return false
+            //会所房间不支持最小化
+            return AppUtil.currentActivity
+                ?.let { !DISMISS_ACTIVITIES.contains(it.javaClass.name) }
+                ?: false
+        }
+
+    override fun init() {
+        roomService.joinController.addListener(this)
+        AppUtil.registerActivityLifecycleCallbacks(this)
+    }
+
+    override fun onActivityResumed(activity: Activity) {
+        super.onActivityResumed(activity)
+        Log.d(TAG, "onActivityResumed")
+        showMinimizeRoomIfNeed(activity)
+    }
+
+    override fun onRoomStateChanged(
+        fromState: RoomState,
+        toState: RoomState,
+        flowStateInfo: FlowStateInfo
+    ) {
+        when (toState) {
+            RoomState.ROOM_IN -> {
+                onRoomIn(flowStateInfo.roomId, flowStateInfo)
+            }
+
+            RoomState.ROOM_LEAVE -> {
+                onRoomLeaved(flowStateInfo.roomId, flowStateInfo)
+            }
+
+            else -> {}
+        }
+    }
+
+    private fun onRoomIn(roomId: String, flowStateInfo: FlowStateInfo) {
+        Log.d(TAG, "onRoomIn")
+        removeMinimizedRoomView()
+    }
+
+    private fun onRoomLeaved(roomId: String, flowStateInfo: FlowStateInfo) {
+        Log.d(TAG, "onRoomLeaved")
+        removeMinimizedRoomView()
+    }
+
+    private fun checkShowOrNot(activity: Activity?): Boolean {
+        val roomInfo = roomService.joinController.joinedRoomInfo
+        val joinRoomState = roomService.joinController.getJoinRoomState()
+        Log.d(
+            TAG,
+            "checkShowOrNot, roomInfo:$roomInfo, joinRoomState:$joinRoomState, activity:$activity"
+        )
+        if (roomInfo == null) {
+            //无进房信息
+            return false
+        }
+
+        if (activity != null) {
+            return !DISMISS_ACTIVITIES.contains(activity.javaClass.name)
+        }
+
+        return true
+    }
+
+    private fun showMinimizeRoomIfNeed(activity: Activity?) {
+        Log.d(TAG, "showMinimizeRoomIfNeed")
+        if (checkShowOrNot(activity)) {
+            addMinimizedRoomView()
+        } else {
+            removeMinimizedRoomView()
+        }
+    }
+
+    override fun addMinimizedRoomView() {
+        Log.d(TAG, "addMinimizedRoomView")
+        runOnUiThread {
+            if (minimizedRoomFloatView != null) {
+                minimizedRoomFloatView?.show()
+                return@runOnUiThread
+            }
+            minimizedRoomFloatView =
+                floatViewFactory.createFloatView(MinimizedRoomFloatData(MODE_APPLICATION))
+            minimizedRoomFloatView?.let {
+                WindowManagerProxy.getWindowManager().addView(it)
+            }
+            minimizedRoomFloatView?.setOnClickListener {
+                val activity = AppUtil.currentActivity ?: return@setOnClickListener
+                val roomId =
+                    roomService.joinController.getJoinedRoomId() ?: return@setOnClickListener
+                Router.build(activity, Room.Room.PATH)
+                    .putExtra(
+                        Room.Room.EXTRA_ENTER_ROOM_INFO,
+                        EnterRoomInfo(roomId)
+                    )
+                    .start()
+            }
+            minimizedRoomFloatView?.setOnCloseClick {
+                handleExitRoom(LeaveRoomReason.INITIATIVE)
+            }
+            minimizedRoomFloatView?.show()
+        }
+    }
+
+    override fun removeMinimizedRoomView() {
+        Log.d(TAG, "removeMinimizedRoomView")
+        runOnUiThread {
+            minimizedRoomFloatView?.let {
+                it.hide()
+                WindowManagerProxy.getWindowManager().removeView(it)
+            }
+            minimizedRoomFloatView = null
+        }
+    }
+
+    // TODO: zhangfei 踢人场景
+//    override fun onKickOutRoom(kickReason: Long) {
+//        runOnUiThread {
+//            if (minimizedRoomFloatView?.isVisible == true) {
+//                val activity = AppUtil.currentActivity as? FragmentActivity ?: return@runOnUiThread
+//                CommonDialog.Builder()
+//                    .message(getCompatString(R.string.room_kick_out_tip))
+//                    .onPositive {
+//                        handleExitRoom(LeaveRoomReason.KICK_OUT)
+//                    }
+//                    .build()
+//                    .show(activity.supportFragmentManager, "KickedOutTipDialog")
+//            }
+//        }
+//    }
+
+    private fun handleExitRoom(reason: LeaveRoomReason) {
+        CoroutineScope(Dispatcher.UI).launch {
+            roomService.joinController.leaveRoom(reason)
+        }
+        removeMinimizedRoomView()
+    }
+
+    companion object {
+        private const val TAG = "MinimizeRoomManager"
+
+        private val DISMISS_ACTIVITIES = hashSetOf<String>().apply {
+            Router.getClazz(Room.Room.PATH)?.let { this.add(it.name) }
+        }
+    }
+}

+ 12 - 0
module/room/src/main/java/com/adealink/weparty/room/minimize/view/MinimizedRoomFloatData.kt

@@ -0,0 +1,12 @@
+package com.adealink.weparty.room.minimize.view
+
+
+import com.adealink.weparty.commonui.widget.floatview.data.FloatWindowType
+import com.adealink.weparty.commonui.widget.floatview.data.IWindowFloatData
+
+class MinimizedRoomFloatData(private val windowMode: Int) : IWindowFloatData {
+    override fun windowMode(): Int = windowMode
+
+    override fun windowType(): FloatWindowType = FloatWindowType.MINIMIZE_ROOM
+
+}

+ 84 - 0
module/room/src/main/java/com/adealink/weparty/room/minimize/view/MinimizedRoomFloatView.kt

@@ -0,0 +1,84 @@
+package com.adealink.weparty.room.minimize.view
+
+import android.animation.ObjectAnimator
+import android.animation.ValueAnimator
+import android.view.LayoutInflater
+import android.view.View
+import android.view.animation.LinearInterpolator
+import com.adealink.frame.util.DisplayUtil
+import com.adealink.weparty.commonui.widget.floatview.view.BaseDragFloatView
+import com.adealink.weparty.module.profile.ProfileModule
+import com.adealink.weparty.room.databinding.LayoutMinimizedRoomFloatViewBinding
+import com.adealink.weparty.room.sdk.service.roomService
+
+
+class MinimizedRoomFloatView(floatData: MinimizedRoomFloatData) : BaseDragFloatView(floatData) {
+
+    private var binding: LayoutMinimizedRoomFloatViewBinding? = null
+    private var closeClick: (() -> Unit)? = null
+    private var rotatingAnim: ObjectAnimator? = null
+
+    override fun onCreate() {
+        super.onCreate()
+        val binding = LayoutMinimizedRoomFloatViewBinding.inflate(LayoutInflater.from(context))
+        this.binding = binding
+        setContentView(binding.root)
+        binding.btnClose.setOnClickListener {
+            closeClick?.invoke()
+        }
+        roomService.joinController.joinedRoomInfo?.let {
+            // TODO: zhangfei 房间封面
+            binding.ivAvatar.setImageUrl(ProfileModule.getMyUserInfo()?.avatar)
+        }
+        rotatingAnim =
+            ObjectAnimator.ofFloat(binding.ivAvatar, "rotation", 0f, 360f)
+                .setDuration(4000L)
+        rotatingAnim?.interpolator = LinearInterpolator()
+        rotatingAnim?.repeatCount = ValueAnimator.INFINITE
+    }
+
+    override fun getLayoutParamWidth(): Int {
+        return DisplayUtil.dp2px(75f)
+    }
+
+    override fun getLayoutParamHeight(): Int {
+        return DisplayUtil.dp2px(72f)
+    }
+
+    override fun getClickableViews(): List<View>? {
+        val clickBtn = binding?.btnClose ?: return null
+        return listOf(clickBtn)
+    }
+
+    override fun getLayoutParamX(): Int {
+        return DisplayUtil.getScreenWidth() - getLayoutParamWidth() - DisplayUtil.dp2px(20f)
+    }
+
+    override fun getLayoutParamY(): Int {
+        return DisplayUtil.getScreenHeight() - getLayoutParamHeight() - DisplayUtil.dp2px(71f)
+    }
+
+    override fun applySnapToEdge(): Boolean {
+        return false
+    }
+
+    fun setOnCloseClick(click: (() -> Unit)?) {
+        this.closeClick = click
+    }
+
+    fun show() {
+        visibility = View.VISIBLE
+        rotatingAnim?.cancel()
+        rotatingAnim?.start()
+    }
+
+    fun hide() {
+        visibility = View.GONE
+        rotatingAnim?.cancel()
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        rotatingAnim?.cancel()
+    }
+}

+ 37 - 0
module/room/src/main/res/layout/layout_minimized_room_float_view.xml

@@ -0,0 +1,37 @@
+<?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"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_bg"
+        android:layout_width="67dp"
+        android:layout_height="67dp"
+        android:layout_marginTop="4.5dp"
+        android:layout_marginEnd="7.5dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <com.adealink.weparty.commonui.imageview.AvatarView
+            android:id="@+id/iv_avatar"
+            android:layout_width="54dp"
+            android:layout_height="54dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:roundingBorderColor="@color/white"
+            app:roundingBorderWidth="1dp" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.appcompat.widget.AppCompatImageView
+        android:id="@+id/btn_close"
+        android:layout_width="19dp"
+        android:layout_height="19dp"
+        android:src="@drawable/common_clear_black_36_ic"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>