11package com.trtc.uikit.roomkit.view
22
3+ import android.annotation.SuppressLint
34import android.app.Activity
45import android.app.Dialog
56import android.content.Context
67import android.content.Intent
8+ import android.content.pm.ActivityInfo
9+ import android.content.res.Configuration
710import android.util.AttributeSet
811import android.view.LayoutInflater
12+ import android.widget.ImageView
913import androidx.core.content.ContextCompat
1014import com.trtc.uikit.roomkit.R
1115import com.trtc.uikit.roomkit.aitranscription.AIMinutesActivity
@@ -29,8 +33,8 @@ import com.trtc.uikit.roomkit.base.ui.RoomAlertDialog
2933import com.trtc.uikit.roomkit.view.main.ParticipantManagerView
3034import com.trtc.uikit.roomkit.view.main.RoomBottomBarView
3135import com.trtc.uikit.roomkit.view.main.RoomBottomBarViewListener
32- import com.trtc.uikit.roomkit.view.main.RoomTopBarView
3336import com.trtc.uikit.roomkit.view.main.RoomRecordingFloatingView
37+ import com.trtc.uikit.roomkit.view.main.RoomTopBarView
3438import com.trtc.uikit.roomkit.view.main.RoomView
3539import com.trtc.uikit.roomkit.view.main.screenshare.ScreenShareOverlayView
3640import io.trtc.tuikit.atomicx.widget.basicwidget.toast.AtomicToast
@@ -46,12 +50,13 @@ import io.trtc.tuikit.atomicxcore.api.room.CreateRoomOptions
4650import io.trtc.tuikit.atomicxcore.api.room.DeviceRequestInfo
4751import io.trtc.tuikit.atomicxcore.api.room.KickedOutOfRoomReason
4852import io.trtc.tuikit.atomicxcore.api.room.ParticipantRole
53+ import io.trtc.tuikit.atomicxcore.api.room.RecordingStatus
54+ import io.trtc.tuikit.atomicxcore.api.room.RecordingStopReason
4955import io.trtc.tuikit.atomicxcore.api.room.RoomInfo
5056import io.trtc.tuikit.atomicxcore.api.room.RoomListener
5157import io.trtc.tuikit.atomicxcore.api.room.RoomParticipant
5258import io.trtc.tuikit.atomicxcore.api.room.RoomParticipantListener
5359import io.trtc.tuikit.atomicxcore.api.room.RoomParticipantStore
54- import io.trtc.tuikit.atomicxcore.api.room.RecordingStopReason
5560import io.trtc.tuikit.atomicxcore.api.room.RoomStore
5661import io.trtc.tuikit.atomicxcore.api.room.RoomType
5762import io.trtc.tuikit.atomicxcore.api.room.RoomUser
@@ -105,6 +110,8 @@ class RoomMainView @JvmOverloads constructor(
105110 private val barrageStreamView: BarrageStreamView by lazy { findViewById(R .id.barrage_stream_view) }
106111 private val screenShareOverlayView: ScreenShareOverlayView by lazy { findViewById(R .id.screen_share_overlay_view) }
107112 private val recordingFloatingView: RoomRecordingFloatingView by lazy { findViewById(R .id.recording_floating_view) }
113+ private val orientationSwitchButton: ImageView by lazy { findViewById(R .id.orientation_switch_button) }
114+ private var currentScreenSharerID: String? = null
108115
109116 private var roomType = RoomType .STANDARD
110117 private val roomStore = RoomStore .shared()
@@ -337,12 +344,21 @@ class RoomMainView @JvmOverloads constructor(
337344 barrageStreamView.visibility = GONE
338345 }
339346 RoomDataReporter .reportComponent()
347+ orientationSwitchButton.setOnClickListener {
348+ switchOrientation()
349+ }
350+ updateOrientationVisibility(resources.configuration.orientation)
340351 when (behavior) {
341352 is RoomBehavior .Create -> createRoom(roomID, behavior.options)
342353 is RoomBehavior .Join -> joinRoom(roomID)
343354 }
344355 }
345356
357+ override fun onConfigurationChanged (newConfig : Configuration ) {
358+ super .onConfigurationChanged(newConfig)
359+ updateOrientationVisibility(newConfig.orientation)
360+ }
361+
346362 override fun initStore (roomID : String ) {
347363 participantStore = RoomParticipantStore .create(roomID)
348364 }
@@ -358,6 +374,12 @@ class RoomMainView @JvmOverloads constructor(
358374 .distinctUntilChanged()
359375 .collect { screenShareOverlayView.updateScreenStatus(it) }
360376 }
377+ scope.launch {
378+ participantStore.state.participantWithScreen
379+ .map { it?.userID }
380+ .distinctUntilChanged()
381+ .collect(::onScreenSharerChanged)
382+ }
361383 }
362384
363385 override fun removeObserver () {
@@ -698,6 +720,67 @@ class RoomMainView @JvmOverloads constructor(
698720 return AIMinutesActivity .getForegroundInstance() ? : context
699721 }
700722
723+ private fun updateOrientationVisibility (orientation : Int ) {
724+ val isLandscape = orientation == Configuration .ORIENTATION_LANDSCAPE
725+ topBarView.visibility = if (isLandscape) GONE else VISIBLE
726+ bottomBarView.visibility = if (isLandscape) GONE else VISIBLE
727+ if (isLandscape) aiSubtitleView.visibility = GONE
728+ if (roomType == RoomType .WEBINAR ) {
729+ barrageInputView.visibility = if (isLandscape) GONE else VISIBLE
730+ barrageStreamView.visibility = if (isLandscape) GONE else VISIBLE
731+ }
732+ recordingFloatingView.visibility = when {
733+ isLandscape -> GONE
734+ roomStore.state.currentRoom.value?.recordingInfo?.status == RecordingStatus .RECORDING -> VISIBLE
735+ else -> GONE
736+ }
737+ updateOrientationSwitchButtonVisibility(orientation)
738+ }
739+
740+ private fun updateOrientationSwitchButtonVisibility (
741+ orientation : Int = resources.configuration.orientation
742+ ) {
743+ val hasRemoteSharer = currentScreenSharerID != null && currentScreenSharerID != localUserID
744+ val shouldShow = roomType != RoomType .WEBINAR && hasRemoteSharer
745+ orientationSwitchButton.visibility = if (shouldShow) VISIBLE else GONE
746+ val isLandscape = orientation == Configuration .ORIENTATION_LANDSCAPE
747+ orientationSwitchButton.setImageResource(
748+ if (isLandscape) R .drawable.roomkit_ic_switch_portrait_button
749+ else R .drawable.roomkit_ic_switch_landscape_button
750+ )
751+ }
752+
753+ @SuppressLint(" SourceLockedOrientationActivity" )
754+ private fun switchOrientation () {
755+ val activity = context as ? Activity ? : return
756+ val currentlyLandscape =
757+ resources.configuration.orientation == Configuration .ORIENTATION_LANDSCAPE
758+ activity.requestedOrientation = if (currentlyLandscape) {
759+ ActivityInfo .SCREEN_ORIENTATION_PORTRAIT
760+ } else {
761+ ActivityInfo .SCREEN_ORIENTATION_LANDSCAPE
762+ }
763+ }
764+
765+ @SuppressLint(" SourceLockedOrientationActivity" )
766+ private fun forcePortraitIfLandscape () {
767+ val activity = context as ? Activity ? : return
768+ if (resources.configuration.orientation == Configuration .ORIENTATION_LANDSCAPE ) {
769+ activity.requestedOrientation = ActivityInfo .SCREEN_ORIENTATION_PORTRAIT
770+ }
771+ }
772+
773+ private fun onScreenSharerChanged (newSharerID : String? ) {
774+ if (currentScreenSharerID == newSharerID) {
775+ return
776+ }
777+ currentScreenSharerID = newSharerID
778+ updateOrientationSwitchButtonVisibility()
779+ if (newSharerID.isNullOrEmpty()) {
780+ forcePortraitIfLandscape()
781+ }
782+ }
783+
701784 fun isAISubtitleVisible (): Boolean {
702785 return aiSubtitleView.visibility == VISIBLE
703786 }
0 commit comments