Skip to content

Commit

Permalink
Merge pull request #606 from 100mslive/dev
Browse files Browse the repository at this point in the history
Release 1.1.92
  • Loading branch information
PratimMallick authored Jan 19, 2024
2 parents 9eb4c53 + dc5569f commit a3253da
Show file tree
Hide file tree
Showing 21 changed files with 534 additions and 152 deletions.
1 change: 0 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ kotlin.code.style=official
100MS_APP_VERSION_CODE=643
100MS_APP_VERSION_NAME=5.8.872
hmsRoomKitGroup=live.100ms
HMS_ROOM_KIT_VERSION=1.1.91
HMS_ROOM_KIT_VERSION=1.1.92
android.suppressUnsupportedCompileSdk=33
2 changes: 1 addition & 1 deletion room-kit/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.percentlayout:percentlayout:1.0.0'

def hmsVersion = "2.8.7"
def hmsVersion = "2.8.9"
// To add dependencies of specific module
implementation "live.100ms:android-sdk:$hmsVersion"
implementation "live.100ms:video-view:$hmsVersion"
Expand Down
1 change: 0 additions & 1 deletion room-kit/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Expand Down
9 changes: 9 additions & 0 deletions room-kit/src/main/java/live/hms/roomkit/ViewExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.graphics.drawable.GradientDrawable
import android.net.Uri
import android.os.Build
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import android.view.*
import android.view.accessibility.AccessibilityManager
Expand All @@ -28,6 +29,7 @@ import live.hms.video.media.tracks.HMSLocalVideoTrack
import live.hms.video.media.tracks.HMSRemoteVideoTrack
import live.hms.video.media.tracks.HMSVideoTrack
import live.hms.videoview.HMSVideoView
import org.w3c.dom.Text
import org.webrtc.EglRenderer
import org.webrtc.SurfaceViewRenderer
import java.io.File
Expand Down Expand Up @@ -119,6 +121,13 @@ fun Fragment.hideKeyboard() {
view?.let { activity?.hideKeyboard(it) }
}

fun TextView.horizontalscroll() {
setEllipsize(TextUtils.TruncateAt.MARQUEE);
setSingleLine(true);
setMarqueeRepeatLimit(-1);
setSelected(true);
}

fun Activity.hideKeyboard() {
hideKeyboard(currentFocus ?: View(this))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import androidx.core.os.bundleOf
import androidx.core.view.*
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
Expand Down Expand Up @@ -177,12 +178,14 @@ class MeetingFragment : Fragment() {
super.onDestroy()
isCountdownManuallyCancelled = true
hasStartedHls = false
meetingViewModel.setCountDownTimerStartedAt(null)
countDownTimer?.cancel()
}

override fun onPause() {
super.onPause()
isCountdownManuallyCancelled = true
meetingViewModel.setCountDownTimerStartedAt(null)
countDownTimer?.cancel()
}

Expand Down Expand Up @@ -226,16 +229,15 @@ class MeetingFragment : Fragment() {

private fun setupStreamingTimeView() {
countDownTimer?.cancel()
meetingViewModel.setCountDownTimerStartedAt(null)
countDownTimer = object : CountDownTimer(1000, 1000) {
override fun onTick(l: Long) {
val startedAt =
meetingViewModel.hmsSDK.getRoom()?.hlsStreamingState?.variants?.firstOrNull()?.startedAt
?: meetingViewModel.hmsSDK.getRoom()?.rtmpHMSRtmpStreamingState?.startedAt
startedAt?.let {
if (startedAt > 0) {
binding.tvStreamingTime.visibility = View.VISIBLE
binding.tvStreamingTime.text =
millisecondsToTime(System.currentTimeMillis().minus(startedAt))
meetingViewModel.setCountDownTimerStartedAt(startedAt)
}
}
}
Expand Down Expand Up @@ -295,6 +297,15 @@ class MeetingFragment : Fragment() {
initObservers()
initOnBackPress()

meetingViewModel.countDownTimerStartedAt.observe(viewLifecycleOwner) { startedAt ->
if (startedAt != null) {
binding.tvStreamingTime.visibility = View.VISIBLE
binding.tvStreamingTime.text =
millisecondsToTime(System.currentTimeMillis().minus(startedAt))
} else {
binding.tvStreamingTime.visibility = View.GONE
}
}
binding.chatMessages.isHeightContrained = true
PauseChatUIUseCase().setChatPauseVisible(
binding.chatOptionsCard,
Expand Down Expand Up @@ -707,7 +718,7 @@ class MeetingFragment : Fragment() {
}

private fun startHLSStreamingIfRequired() {
if (args.startHlsStream && meetingViewModel.isAllowedToHlsStream()) {
if (args.startHlsStream && meetingViewModel.isAllowedToHlsStream() && meetingViewModel.isHlsRunning().not()) {
binding.meetingFragmentProgress.visibility = View.VISIBLE
hasStartedHls = true
meetingViewModel.startHls(settings.lastUsedMeetingUrl, HMSHlsRecordingConfig(true, false))
Expand Down Expand Up @@ -1239,14 +1250,33 @@ class MeetingFragment : Fragment() {
Log.v(TAG, "iconOutputDevice.onClick()")

AudioOutputSwitchBottomSheet { audioDevice, isMuted ->
updateActionVolumeMenuIcon(audioDevice)

if (isMuted)
updateActionVolumeMenuIcon()
}.show(
childFragmentManager, MeetingFragment.AudioSwitchBottomSheetTAG
)
}
}

updateActionVolumeMenuIcon(meetingViewModel.getAudioOutputRouteType())
meetingViewModel.hmsSDK.setAudioDeviceChangeListener(object :
HMSAudioManager.AudioManagerDeviceChangeListener {
override fun onAudioDeviceChanged(
p0: HMSAudioManager.AudioDevice,
p1: Set<HMSAudioManager.AudioDevice>
) {
meetingViewModel.updateAudioDeviceChange(p0)
}


override fun onError(p0: HMSException) {
}
})

meetingViewModel.audioDeviceChange.observe(viewLifecycleOwner, Observer{
updateActionVolumeMenuIcon(it)
})


binding.buttonSwitchCamera.setOnSingleClickListener(200L) {
meetingViewModel.flipCamera()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package live.hms.roomkit.ui.meeting

import android.app.Application
import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.util.Log
Expand All @@ -28,6 +27,7 @@ import live.hms.roomkit.ui.settings.SettingsStore
import live.hms.roomkit.ui.theme.HMSPrebuiltTheme
import live.hms.roomkit.util.POLL_IDENTIFIER_FOR_HLS_CUE
import live.hms.roomkit.util.SingleLiveEvent
import live.hms.video.audio.HMSAudioManager
import live.hms.video.connection.stats.*
import live.hms.video.error.HMSException
import live.hms.video.interactivity.HmsInteractivityCenter
Expand Down Expand Up @@ -72,6 +72,7 @@ class MeetingViewModel(
var recNum = 0
// This is needed in chat for it to determine what kind of chat it is.
val initPrebuiltChatMessageRecipient = MutableLiveData<Pair<Recipient?,Int>>()
val audioDeviceChange = MutableLiveData<HMSAudioManager.AudioDevice>()
val participantPreviousRoleChangeUseCase by lazy { ParticipantPreviousRoleChangeUseCase(hmsSDK::changeMetadata)}
private var hasValidToken = false
private var pendingRoleChange: HMSRoleChangeRequest? = null
Expand Down Expand Up @@ -1092,12 +1093,17 @@ class MeetingViewModel(
}

fun triggerPollsNotification(poll: HmsPoll) {

val res = getApplication<Application>().resources
val pollOrQuiz = res.getString(if (poll.category == HmsPollCategory.POLL) R.string.hms_poll else R.string.hms_quiz)
val actionButtonText = res.getString(if (poll.category == HmsPollCategory.POLL) R.string.hms_vote else R.string.hms_answer)

hmsNotificationEvent.postValue(
HMSNotification(
title = "${poll.createdBy?.name.orEmpty()} started a new ${if (poll.category == HmsPollCategory.POLL) "poll" else "quiz"}",
title = res.getString(R.string.hms_started_quiz_poll_notification, poll.createdBy?.name.orEmpty(), pollOrQuiz),
isDismissible = true,
icon = R.drawable.poll_vote,
actionButtonText = if (poll.category == HmsPollCategory.POLL) "Vote" else "Join",
actionButtonText = actionButtonText,
type = HMSNotificationType.OpenPollOrQuiz(pollId = poll.pollId)
)
)
Expand Down Expand Up @@ -2120,14 +2126,14 @@ class MeetingViewModel(
}
return valid
}
fun saveInfoSingleChoice(question : HMSPollQuestion, option: Int?, hmsPoll: HmsPoll) : Boolean {
fun saveInfoSingleChoice(question : HMSPollQuestion, option: Int?, hmsPoll: HmsPoll, timeTakenMillis : Long) : Boolean {
if(option == null) {
return false
}
val answer = question.options?.get(option)
if(answer != null) {
val response = HMSPollResponseBuilder(hmsPoll, null)
.addResponse(question, answer)
.addResponse(question, answer, timeTakenMillis)
localHmsInteractivityCenter.add(response, object : HmsTypedActionResultListener<PollAnswerResponse>{
override fun onSuccess(result: PollAnswerResponse) {
Log.d("PollAnswer","Success")
Expand All @@ -2146,14 +2152,14 @@ class MeetingViewModel(
//
// localHmsInteractivityCenter.add()
}
fun saveInfoMultiChoice(question : HMSPollQuestion, options : List<Int>?, hmsPoll: HmsPoll) : Boolean {
fun saveInfoMultiChoice(question : HMSPollQuestion, options : List<Int>?, hmsPoll: HmsPoll, timeTakenMillis : Long) : Boolean {
val valid = options != null
val answer = question.options?.filterIndexed { index, hmsPollQuestionOption ->
options?.contains(index) == true
}
if(valid && answer != null) {
val response = HMSPollResponseBuilder(hmsPoll, null)
.addResponse(question, answer)
.addResponse(question, answer, timeTakenMillis)
localHmsInteractivityCenter.add(response, object : HmsTypedActionResultListener<PollAnswerResponse>{
override fun onSuccess(result: PollAnswerResponse) {
Log.d("PollAnswer","Success $result")
Expand Down Expand Up @@ -2383,5 +2389,18 @@ class MeetingViewModel(
}

fun disableNameEdit() = prebuiltOptions?.userName != null

val countDownTimerStartedAt = MutableLiveData<Long?>(null)
fun setCountDownTimerStartedAt(startedAt: Long?) {
countDownTimerStartedAt.postValue(startedAt)
}

fun updateAudioDeviceChange(p0: HMSAudioManager.AudioDevice) {
audioDeviceChange.postValue(p0)
}

private val questionTimingUseCase = QuizQuestionTimingUseCase()
val setQuestionStartTime = questionTimingUseCase::setQuestionStartTime
val getQuestionStartTime = questionTimingUseCase::getQuestionStartTime
}

Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import live.hms.roomkit.util.setOnSingleClickListener
import live.hms.roomkit.util.switchCamera
import live.hms.roomkit.util.viewLifecycle
import live.hms.video.audio.HMSAudioManager
import live.hms.video.error.HMSException
import live.hms.video.media.tracks.HMSLocalAudioTrack
import live.hms.video.media.tracks.HMSLocalVideoTrack
import live.hms.video.sdk.models.HMSLocalPeer
Expand Down Expand Up @@ -360,13 +361,32 @@ class PreviewFragment : Fragment() {
goToHomePage()
}
}
updateActionVolumeMenuIcon(meetingViewModel.getAudioOutputRouteType())
meetingViewModel.hmsSDK.setAudioDeviceChangeListener(object :
HMSAudioManager.AudioManagerDeviceChangeListener {
override fun onAudioDeviceChanged(
p0: HMSAudioManager.AudioDevice,
p1: Set<HMSAudioManager.AudioDevice>
) {
meetingViewModel.updateAudioDeviceChange(p0)
}


override fun onError(p0: HMSException) {
}
})

meetingViewModel.audioDeviceChange.observe(viewLifecycleOwner, Observer{
updateActionVolumeMenuIcon(it)
})

binding.iconOutputDevice.apply {
setOnSingleClickListener(200L) {
Log.v(TAG, "iconOutputDevice.onClick()")

AudioOutputSwitchBottomSheet { audioDevice, isMuted ->
updateActionVolumeMenuIcon(audioDevice)
if (isMuted)
updateActionVolumeMenuIcon()
}.show(
childFragmentManager, MeetingFragment.AudioSwitchBottomSheetTAG
)
Expand Down Expand Up @@ -663,7 +683,7 @@ class PreviewFragment : Fragment() {
updateJoinButtonTextIfHlsIsEnabled(room.localPeer?.hmsRole?.name)
enableDisableJoinNowButton()
binding.buttonJoinMeeting.visibility = View.VISIBLE
updateActionVolumeMenuIcon(meetingViewModel.getAudioOutputRouteType())

} else {
updateActionVolumeMenuIcon()
binding.buttonJoinMeeting.visibility = View.VISIBLE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package live.hms.roomkit.ui.meeting

import android.util.Log
import live.hms.roomkit.ui.polls.display.QuestionContainer

class QuizQuestionTimingUseCase {
private val questionSeenTimeMap = hashMapOf<String, Long>()
fun setQuestionStartTime(question: QuestionContainer.Question) {
val id = getIdForQuestion(question)
if (!questionSeenTimeMap.contains(id)) {
Log.d("VerifyAnswer", "Seen $id")
// save it without overwriting existing values
questionSeenTimeMap[id] = System.currentTimeMillis()
}
}

fun getQuestionStartTime(question: QuestionContainer.Question): Long? {
return questionSeenTimeMap.getOrDefault(getIdForQuestion(question), null)
}

private fun getIdForQuestion(question: QuestionContainer.Question): String {
val pollId = question.poll.pollId
val questionId = question.question.questionID
return "$pollId/$questionId"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.xwray.groupie.ExpandableItem
import com.xwray.groupie.viewbinding.BindableItem
import live.hms.roomkit.R
import live.hms.roomkit.databinding.LayoutPinnedMessageBinding
import live.hms.roomkit.horizontalscroll
import live.hms.roomkit.setOnSingleClickListener
import live.hms.roomkit.ui.meeting.SessionMetadataUseCase
import live.hms.roomkit.ui.theme.applyTheme
Expand All @@ -24,6 +25,7 @@ class PinnedMessageItem(val receivedPinnedMessage: SessionMetadataUseCase.Pinned
with(viewBinding) {
applyTheme()
pinnedMessage.text = boldTheSenderName(receivedPinnedMessage.text)
pinnedMessage.horizontalscroll()
root.setOnSingleClickListener {
expand.onToggleExpanded()
pinnedMessage.maxLines = if(expand.isExpanded) {
Expand Down
Loading

0 comments on commit a3253da

Please sign in to comment.