Merge pull request #1112 from Azure/release/calling-1.12.0

[Calling][Release] Calling release 1.12.0
This commit is contained in:
ShaunaSong 2024-10-31 16:25:47 -07:00 коммит произвёл GitHub
Родитель d7e46c6063 2adb5ebc6c
Коммит 13473b617e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
71 изменённых файлов: 645 добавлений и 348 удалений

Просмотреть файл

@ -5,7 +5,7 @@ buildscript {
}
ext {
call_library_version_name = '1.11.0'
call_library_version_name = '1.12.0'
chat_library_version_name = '1.0.0-beta.3'
ui_library_version_code = getVersionCode()

Просмотреть файл

@ -59,56 +59,5 @@ publishing {
from components.release
}
}
callingSDK(MavenPublication) {
pom {
name = "Microsoft Azure Android Voice & Video Calling Library for Communication Services"
description = "This package contains Android client library code for enabling Voice and Video Calling capabilities for Azure Communication Services"
url = "https://github.com/Azure/azure-sdk-for-android"
licenses {
license {
name = 'Licensed under the Microsoft Software License Terms for the Azure Communications Services, Azure CPaaS, AZURE COMMUNICATION SERVICES VOICE AND VIDEO CALLING CLIENT LIBRARY. See EULA.txt for license information.'
url = 'https://repo.maven.apache.org/maven2/com/azure/android/azure-communication-calling/1.0.0-beta.1/azure-communication-calling-1.0.0-beta.1-eula.md'
}
}
developers {
developer {
id = 'Microsoft'
name = 'Microsoft'
}
}
scm {
connection = 'scm:git:git://github.com/Azure/communication-ui-library-android.git'
developerConnection = 'scm:git:ssh:github.com:Azure/communication-ui-library-android.git'
url = 'https://github.com/Azure/communication-ui-library-android'
}
}
groupId 'com.azure.android'
artifactId 'azure-communication-calling'
version '2.2.0-pre-validation'
artifact("/Users/pavelprystinka/Documents/GitHub/package-host/SDK/calling/azure-communication-calling-2.2.0-pre-validation.aar")
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', 'com.azure.android')
dependencyNode.appendNode('artifactId', 'azure-communication-common')
dependencyNode.appendNode('version', '1.0.0')
dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', 'net.sourceforge.streamsupport')
dependencyNode.appendNode('artifactId', 'android-retrofuture')
dependencyNode.appendNode('version', '1.7.3')
dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', 'com.google.code.gson')
dependencyNode.appendNode('artifactId', 'gson')
dependencyNode.appendNode('version', '2.8.6')
}
}
}
}

Просмотреть файл

@ -1,6 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* <CUSTOM_CALL_HEADER> */
package com.azure.android.communication.ui.calling
import androidx.test.platform.app.InstrumentationRegistry
@ -292,4 +291,3 @@ internal class CustomInfoHeaderTest : BaseUiTest() {
assertTextDisplayed(subtitle)
}
}
/* </CUSTOM_CALL_HEADER> */

Просмотреть файл

@ -34,9 +34,7 @@ import com.azure.android.communication.ui.calling.models.CallCompositePictureInP
import com.azure.android.communication.ui.calling.models.CallCompositePushNotification;
import com.azure.android.communication.ui.calling.models.CallCompositeRemoteOptions;
import com.azure.android.communication.ui.calling.models.CallCompositeRemoteParticipantJoinedEvent;
/* <CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.calling.models.CallCompositeRemoteParticipantLeftEvent;
/* </CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.calling.models.CallCompositeRoomLocator;
import com.azure.android.communication.ui.calling.models.CallCompositeParticipantViewData;
import com.azure.android.communication.ui.calling.models.CallCompositeSetParticipantViewDataResult;
@ -581,7 +579,6 @@ public final class CallComposite {
final CallCompositeEventHandler<CallCompositeRemoteParticipantJoinedEvent> eventHandler) {
configuration.getCallCompositeEventsHandler().removeOnRemoteParticipantJoinedEventHandler(eventHandler);
}
/* <CUSTOM_CALL_HEADER> */
/**
* Add {@link CallCompositeEventHandler}.
*
@ -610,7 +607,6 @@ public final class CallComposite {
final CallCompositeEventHandler<CallCompositeRemoteParticipantLeftEvent> eventHandler) {
configuration.getCallCompositeEventsHandler().removeOnRemoteParticipantLeftEventHandler(eventHandler);
}
/* </CUSTOM_CALL_HEADER> */
/**
* Add {@link CallCompositeEventHandler}
*

Просмотреть файл

@ -13,9 +13,7 @@ import com.azure.android.communication.ui.calling.models.CallCompositeUserReport
import com.azure.android.communication.ui.calling.models.CallCompositeAudioSelectionChangedEvent
import com.azure.android.communication.ui.calling.models.CallCompositeIncomingCallCancelledEvent
import com.azure.android.communication.ui.calling.models.CallCompositeIncomingCallEvent
/* <CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.calling.models.CallCompositeRemoteParticipantLeftEvent
/* </CUSTOM_CALL_HEADER> */
internal class CallCompositeEventsHandler {
// mutableSet does preserve element iteration order
@ -23,10 +21,8 @@ internal class CallCompositeEventsHandler {
private val remoteParticipantJoinedHandlers =
mutableSetOf<CallCompositeEventHandler<CallCompositeRemoteParticipantJoinedEvent>>()
/* <CUSTOM_CALL_HEADER> */
private val remoteParticipantRemovedHandlers =
mutableSetOf<CallCompositeEventHandler<CallCompositeRemoteParticipantLeftEvent>>()
/* </CUSTOM_CALL_HEADER> */
private val callStateHandlers =
mutableSetOf<CallCompositeEventHandler<CallCompositeCallStateChangedEvent>>()
@ -61,7 +57,6 @@ internal class CallCompositeEventsHandler {
fun removeOnRemoteParticipantJoinedEventHandler(handler: CallCompositeEventHandler<CallCompositeRemoteParticipantJoinedEvent>) =
remoteParticipantJoinedHandlers.remove(handler)
/* <CUSTOM_CALL_HEADER> */
fun getOnRemoteParticipantRemovedHandlers() = remoteParticipantRemovedHandlers.asIterable()
fun addOnRemoteParticipantLeftEventHandler(handler: CallCompositeEventHandler<CallCompositeRemoteParticipantLeftEvent>) =
@ -69,7 +64,6 @@ internal class CallCompositeEventsHandler {
fun removeOnRemoteParticipantLeftEventHandler(handler: CallCompositeEventHandler<CallCompositeRemoteParticipantLeftEvent>) =
remoteParticipantRemovedHandlers.remove(handler)
/* </CUSTOM_CALL_HEADER> */
fun getOnAudioSelectionChangedEventHandlers() = audioSelectionChangedEventHandlers.asIterable()
fun getOnMultitaskingStateChangedEventHandlers() = multitaskingStateChangedEvent.asIterable()

Просмотреть файл

@ -87,7 +87,5 @@ internal interface DependencyInjectionContainer {
val capabilitiesManager: CapabilitiesManager
val captionsDataManager: CaptionsDataManager
/* <CUSTOM_CALL_HEADER> */
val updatableOptionsManager: UpdatableOptionsManager
/* </CUSTOM_CALL_HEADER> */
}

Просмотреть файл

@ -279,9 +279,7 @@ internal class DependencyInjectionContainerImpl(
private val callDiagnosticsReducer get() = CallDiagnosticsReducerImpl()
private val toastNotificationReducer get() = ToastNotificationReducerImpl()
private val captionsReducer get() = CaptionsReducerImpl()
/* <CUSTOM_CALL_HEADER> */
private val callScreenInformationHeaderReducer get() = CallScreenInformationHeaderReducerImpl()
/* </CUSTOM_CALL_HEADER> */
private val buttonOptionsReducer get() = ButtonViewDataReducerImpl()
/* <RTT_POC>

Просмотреть файл

@ -5,9 +5,7 @@ package com.azure.android.communication.ui.calling.handlers
import com.azure.android.communication.ui.calling.configuration.CallCompositeConfiguration
import com.azure.android.communication.ui.calling.models.CallCompositeRemoteParticipantJoinedEvent
/* <CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.calling.models.buildCallCompositeRemoteParticipantLeftEvent
/* </CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.calling.redux.Store
import com.azure.android.communication.ui.calling.redux.state.ReduxState
import com.azure.android.communication.ui.calling.redux.state.RemoteParticipantsState
@ -54,7 +52,6 @@ internal class RemoteParticipantHandler(
}
private fun sendRemoteParticipantLeftEvent(leftParticipants: List<String>) {
/* <CUSTOM_CALL_HEADER> */
if (configuration.callCompositeEventsHandler.getOnRemoteParticipantRemovedHandlers().any()) {
try {
if (leftParticipants.isNotEmpty()) {
@ -72,7 +69,6 @@ internal class RemoteParticipantHandler(
// suppress any possible application errors
}
}
/* </CUSTOM_CALL_HEADER> */
}
private fun sendRemoteParticipantJoinedEvent(joinedParticipant: List<String>) {

Просмотреть файл

@ -1,10 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* <CUSTOM_CALL_HEADER> */
package com.azure.android.communication.ui.calling.models;
import com.azure.android.communication.ui.calling.CallCompositeEventHandler;
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
import java.util.ArrayList;
import java.util.List;
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
/**
* Options for the {@link CallCompositeCallScreenHeaderViewData}.
*/
@ -14,6 +18,9 @@ public final class CallCompositeCallScreenHeaderViewData {
private String title;
private String subtitle;
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
private List<CallCompositeCustomButtonViewData> customButtons = new ArrayList<>();
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
/**
* Create a {@link CallCompositeCallScreenHeaderViewData} object.
@ -68,5 +75,23 @@ public final class CallCompositeCallScreenHeaderViewData {
public String getTitle() {
return title;
}
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
\**
* Set a custom button to the call composite.
* @param button {@link CallCompositeCallScreenControlBarOptions}
*\
public CallCompositeCallScreenHeaderViewData setCustomButtons(
final List<CallCompositeCustomButtonViewData> button) {
customButtons = button;
return this;
}
\**
* Get a custom button to the call composite.
*\
public List<CallCompositeCustomButtonViewData> getCustomButtons() {
return customButtons;
}
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
}
/* </CUSTOM_CALL_HEADER> */

Просмотреть файл

@ -8,9 +8,7 @@ package com.azure.android.communication.ui.calling.models;
*/
public final class CallCompositeCallScreenOptions {
private CallCompositeCallScreenControlBarOptions controlBarOptions;
/* <CUSTOM_CALL_HEADER> */
private CallCompositeCallScreenHeaderViewData headerViewData;
/* </CUSTOM_CALL_HEADER> */
/**
* Creates a CallCompositeCallScreenOptions object.
*/
@ -35,7 +33,6 @@ public final class CallCompositeCallScreenOptions {
public CallCompositeCallScreenControlBarOptions getControlBarOptions() {
return controlBarOptions;
}
/* <CUSTOM_CALL_HEADER> */
/**
* Set the header options.
* @param headerViewData The header options.
@ -54,5 +51,4 @@ public final class CallCompositeCallScreenOptions {
public CallCompositeCallScreenHeaderViewData getHeaderViewData() {
return headerViewData;
}
/* </CUSTOM_CALL_HEADER> */
}

Просмотреть файл

@ -1,6 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* <CUSTOM_CALL_HEADER> */
package com.azure.android.communication.ui.calling.models
import android.content.Context
@ -21,7 +20,6 @@ internal fun CallCompositeCallScreenHeaderViewData.setSubtitleChangedEventHandle
internal fun CallCompositeCallScreenHeaderViewData.setTitleChangedEventHandler(handler: CallCompositeEventHandler<String?>) {
this.titleChangedEventHandler = handler
}
/* </CUSTOM_CALL_HEADER> */
internal fun createButtonClickEvent(
context: Context,
@ -45,6 +43,10 @@ internal fun CallCompositeCustomButtonViewData.setVisibleChangedEventHandler(han
this.visibleChangedEventHandler = handler
}
internal fun CallCompositeCustomButtonViewData.setDrawableIdChangedEventHandler(handler: CallCompositeEventHandler<Int>) {
this.drawableIdChangedEventHandler = handler
}
internal fun CallCompositeButtonViewData.setEnabledChangedEventHandler(handler: CallCompositeEventHandler<Boolean>) {
this.enabledChangedEventHandler = handler
}

Просмотреть файл

@ -1,6 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* <CUSTOM_CALL_HEADER> */
package com.azure.android.communication.ui.calling.models;
import com.azure.android.communication.common.CommunicationIdentifier;
@ -32,4 +31,3 @@ public final class CallCompositeRemoteParticipantLeftEvent {
return Collections.unmodifiableCollection(identifiers);
}
}
/* </CUSTOM_CALL_HEADER> */

Просмотреть файл

@ -86,9 +86,7 @@ internal open class CallCompositeActivity : AppCompatActivity() {
private val logger get() = container.logger
private val compositeManager get() = container.compositeExitManager
private val compositeDataModel get() = container.captionsDataManager
/* <CUSTOM_CALL_HEADER> */
private val updatableOptionsManager get() = container.updatableOptionsManager
/* </CUSTOM_CALL_HEADER> */
private lateinit var visibilityStatusFlow: MutableStateFlow<VisibilityStatus>
override fun onCreate(savedInstanceState: Bundle?) {
@ -223,7 +221,7 @@ internal open class CallCompositeActivity : AppCompatActivity() {
try {
// This code was added to avoid memory leak
diContainerHolder.container.callCompositeActivityWeakReference = WeakReference(null)
diContainerHolder.container.callCompositeActivityWeakReference.clear()
} catch (e: CallCompositeException) {
// could not retrieve the container
}

Просмотреть файл

@ -119,9 +119,10 @@ internal class CallingViewModel(
floatingHeaderViewModel.init(
state.callState.callingStatus,
remoteParticipantsForGridView.count(),
/* <CUSTOM_CALL_HEADER> */
state.callScreenInfoHeaderState,
/* </CUSTOM_CALL_HEADER> */
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
state.buttonState,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
this::requestCallEndOnBackPressed,
)
@ -294,9 +295,10 @@ internal class CallingViewModel(
floatingHeaderViewModel.update(
totalParticipantCountExceptHidden,
/* <CUSTOM_CALL_HEADER> */
state.callScreenInfoHeaderState
/* </CUSTOM_CALL_HEADER> */
state.callScreenInfoHeaderState,
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
state.buttonState,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
lobbyHeaderViewModel.update(

Просмотреть файл

@ -15,9 +15,9 @@ import androidx.lifecycle.lifecycleScope
import com.azure.android.communication.ui.calling.implementation.R
import com.azure.android.communication.ui.calling.presentation.MultitaskingCallCompositeActivity
import com.azure.android.communication.ui.calling.utilities.isAndroidTV
import com.azure.android.communication.ui.calling.utilities.launchAll
import com.microsoft.fluentui.util.activity
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
internal class InfoHeaderView : ConstraintLayout {
constructor(context: Context) : super(context)
@ -26,11 +26,13 @@ internal class InfoHeaderView : ConstraintLayout {
private lateinit var floatingHeader: ConstraintLayout
private lateinit var headerView: View
private lateinit var participantNumberText: TextView
/* <CUSTOM_CALL_HEADER> */
private lateinit var subtitleText: TextView
/* </CUSTOM_CALL_HEADER> */
private lateinit var displayParticipantsImageButton: ImageButton
private lateinit var backButton: ImageButton
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
private lateinit var customButton1: ImageButton
private lateinit var customButton2: ImageButton
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
private lateinit var infoHeaderViewModel: InfoHeaderViewModel
private lateinit var displayParticipantListCallback: () -> Unit
@ -40,9 +42,7 @@ internal class InfoHeaderView : ConstraintLayout {
headerView = findViewById(R.id.azure_communication_ui_call_floating_header)
participantNumberText =
findViewById(R.id.azure_communication_ui_call_participant_number_text)
/* <CUSTOM_CALL_HEADER> */
subtitleText = findViewById(R.id.azure_communication_ui_call_header_subtitle)
/* </CUSTOM_CALL_HEADER> */
displayParticipantsImageButton =
findViewById(R.id.azure_communication_ui_call_bottom_drawer_button)
displayParticipantsImageButton.setOnClickListener {
@ -57,6 +57,10 @@ internal class InfoHeaderView : ConstraintLayout {
infoHeaderViewModel.requestCallEnd()
}
}
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
customButton1 = findViewById(R.id.azure_communication_ui_call_header_custom_button_1)
customButton2 = findViewById(R.id.azure_communication_ui_call_header_custom_button_2)
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
}
fun start(
@ -68,73 +72,98 @@ internal class InfoHeaderView : ConstraintLayout {
this.infoHeaderViewModel = infoHeaderViewModel
this.displayParticipantListCallback = displayParticipantList
setupAccessibility()
viewLifecycleOwner.lifecycleScope.launch {
if (accessibilityEnabled) {
floatingHeader.visibility = View.VISIBLE
} else {
infoHeaderViewModel.getDisplayFloatingHeaderFlow().collect {
floatingHeader.visibility = if (it) View.VISIBLE else View.GONE
// If we are on television, set the focus to the participants button
if (it && isAndroidTV(context)) {
displayParticipantsImageButton.requestFocus()
viewLifecycleOwner.lifecycleScope.launchAll(
{
if (accessibilityEnabled) {
floatingHeader.visibility = View.VISIBLE
} else {
infoHeaderViewModel.getDisplayFloatingHeaderFlow().collect {
floatingHeader.visibility = if (it) View.VISIBLE else View.GONE
// If we are on television, set the focus to the participants button
if (it && isAndroidTV(context)) {
displayParticipantsImageButton.requestFocus()
}
}
}
}
}
/* <CUSTOM_CALL_HEADER> */
viewLifecycleOwner.lifecycleScope.launch {
infoHeaderViewModel.getTitleStateFlow().collect {
if (it.isNullOrEmpty()) {
return@collect
},
{
infoHeaderViewModel.getTitleStateFlow().collect {
if (it.isNullOrEmpty()) {
return@collect
}
participantNumberText.text = it
}
participantNumberText.text = it
}
}
viewLifecycleOwner.lifecycleScope.launch {
infoHeaderViewModel.getSubtitleStateFlow().collect {
if (it.isNullOrEmpty()) {
subtitleText.visibility = View.GONE
return@collect
},
{
infoHeaderViewModel.getSubtitleStateFlow().collect {
if (it.isNullOrEmpty()) {
subtitleText.visibility = View.GONE
return@collect
}
subtitleText.text = it
subtitleText.visibility = View.VISIBLE
}
subtitleText.text = it
subtitleText.visibility = View.VISIBLE
}
}
/* </CUSTOM_CALL_HEADER> */
},
{
infoHeaderViewModel.getNumberOfParticipantsFlow().collect {
if (!infoHeaderViewModel.getTitleStateFlow().value.isNullOrEmpty()) {
return@collect
}
viewLifecycleOwner.lifecycleScope.launch {
infoHeaderViewModel.getNumberOfParticipantsFlow().collect {
/* <CUSTOM_CALL_HEADER> */
if (!infoHeaderViewModel.getTitleStateFlow().value.isNullOrEmpty()) {
return@collect
participantNumberText.text = when (it) {
0 -> context.getString(R.string.azure_communication_ui_calling_view_info_header_waiting_for_others_to_join)
1 -> context.getString(R.string.azure_communication_ui_calling_view_info_header_call_with_1_person)
else -> resources.getString(
R.string.azure_communication_ui_calling_view_info_header_call_with_n_people,
it
)
}
}
/* </CUSTOM_CALL_HEADER> */
participantNumberText.text = when (it) {
0 -> context.getString(R.string.azure_communication_ui_calling_view_info_header_waiting_for_others_to_join)
1 -> context.getString(R.string.azure_communication_ui_calling_view_info_header_call_with_1_person)
else -> resources.getString(
R.string.azure_communication_ui_calling_view_info_header_call_with_n_people,
it
)
},
{
infoHeaderViewModel.getIsOverlayDisplayedFlow().collect {
if (it) {
ViewCompat.setImportantForAccessibility(
headerView,
ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
)
} else {
ViewCompat.setImportantForAccessibility(
headerView,
ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES
)
}
}
},
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
{
infoHeaderViewModel.getCustomButton1StateFlow().collect { button ->
updateCustomButton(button, customButton1)
}
},
{
infoHeaderViewModel.getCustomButton2StateFlow().collect { button ->
updateCustomButton(button, customButton2)
}
}
}
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
}
viewLifecycleOwner.lifecycleScope.launch {
infoHeaderViewModel.getIsOverlayDisplayedFlow().collect {
if (it) {
ViewCompat.setImportantForAccessibility(headerView, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS)
} else {
ViewCompat.setImportantForAccessibility(headerView, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES)
}
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
private fun updateCustomButton(customButtonEntry: InfoHeaderViewModel.CustomButtonEntry?, customButton: ImageButton) {
customButton.visibility = if (customButtonEntry?.isVisible == true) View.VISIBLE else View.GONE
customButtonEntry?.let {
customButton.isEnabled = customButtonEntry.isEnabled
customButton.setImageResource(customButtonEntry.icon)
customButton.setOnClickListener {
infoHeaderViewModel.onCustomButtonClicked(context, customButtonEntry.id)
}
}
}
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
private fun setupAccessibility() {
displayParticipantsImageButton.contentDescription = context.getString(R.string.azure_communication_ui_calling_view_participant_list_open_accessibility_label)

Просмотреть файл

@ -3,107 +3,138 @@
package com.azure.android.communication.ui.calling.presentation.fragment.calling.header
/* <CUSTOM_CALL_HEADER> */
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
import android.content.Context
import com.azure.android.communication.ui.calling.logger.Logger
import com.azure.android.communication.ui.calling.models.createCustomButtonClickEvent
import com.azure.android.communication.ui.calling.presentation.manager.UpdatableOptionsManager
import com.azure.android.communication.ui.calling.redux.state.ButtonState
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
import com.azure.android.communication.ui.calling.redux.state.CallScreenInfoHeaderState
/* </CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.calling.redux.state.CallingStatus
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import java.util.Timer
import java.util.TimerTask
internal class InfoHeaderViewModel(
val multitaskingEnabled: Boolean
val multitaskingEnabled: Boolean,
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
private val updatableOptionsManager: UpdatableOptionsManager,
private val logger: Logger,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
) {
private lateinit var displayFloatingHeaderFlow: MutableStateFlow<Boolean>
private lateinit var isOverlayDisplayedFlow: MutableStateFlow<Boolean>
private lateinit var numberOfParticipantsFlow: MutableStateFlow<Int>
private lateinit var timer: Timer
private lateinit var requestCallEndCallback: () -> Unit
private var displayedOnLaunch = false
/* <CUSTOM_CALL_HEADER> */
private lateinit var titleStateFlow: MutableStateFlow<String?>
private lateinit var subtitleStateFlow: MutableStateFlow<String?>
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
private var buttonState: ButtonState? = null
private lateinit var customButton1MutableStateFlow: MutableStateFlow<CustomButtonEntry?>
private lateinit var customButton2MutableStateFlow: MutableStateFlow<CustomButtonEntry?>
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
fun getTitleStateFlow(): StateFlow<String?> = titleStateFlow
fun getSubtitleStateFlow(): StateFlow<String?> = subtitleStateFlow
/* </CUSTOM_CALL_HEADER> */
fun getIsOverlayDisplayedFlow(): StateFlow<Boolean> = isOverlayDisplayedFlow
fun getDisplayFloatingHeaderFlow(): StateFlow<Boolean> = displayFloatingHeaderFlow
fun getNumberOfParticipantsFlow(): StateFlow<Int> {
return numberOfParticipantsFlow
fun getNumberOfParticipantsFlow(): StateFlow<Int> = numberOfParticipantsFlow
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
fun getCustomButton1StateFlow(): StateFlow<CustomButtonEntry?> = customButton1MutableStateFlow
fun getCustomButton2StateFlow(): StateFlow<CustomButtonEntry?> = customButton2MutableStateFlow
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
fun init(
callingStatus: CallingStatus,
numberOfRemoteParticipants: Int,
callScreenInfoHeaderState: CallScreenInfoHeaderState,
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
buttonState: ButtonState,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
requestCallEndCallback: () -> Unit,
) {
titleStateFlow = MutableStateFlow(callScreenInfoHeaderState.title)
subtitleStateFlow = MutableStateFlow(callScreenInfoHeaderState.subtitle)
displayFloatingHeaderFlow = MutableStateFlow(false)
numberOfParticipantsFlow = MutableStateFlow(numberOfRemoteParticipants)
isOverlayDisplayedFlow = MutableStateFlow(isOverlayDisplayed(callingStatus))
this.requestCallEndCallback = requestCallEndCallback
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
this.buttonState = buttonState
customButton1MutableStateFlow = MutableStateFlow(null)
customButton2MutableStateFlow = MutableStateFlow(null)
updateCustomButtonsState(buttonState)
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
}
fun update(
numberOfRemoteParticipants: Int,
/* <CUSTOM_CALL_HEADER> */
callScreenInfoHeaderState: CallScreenInfoHeaderState,
/* </CUSTOM_CALL_HEADER> */
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
buttonState: ButtonState,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
) {
/* <CUSTOM_CALL_HEADER> */
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
this.buttonState = buttonState
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
titleStateFlow.value = callScreenInfoHeaderState.title
subtitleStateFlow.value = callScreenInfoHeaderState.subtitle
/* </CUSTOM_CALL_HEADER> */
numberOfParticipantsFlow.value = numberOfRemoteParticipants
if (!displayedOnLaunch) {
displayedOnLaunch = true
switchFloatingHeader()
}
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
updateCustomButtonsState(buttonState)
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
}
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
private fun updateCustomButtonsState(buttonState: ButtonState) {
buttonState.callScreenHeaderCustomButtonsState.firstOrNull()?.let {
val customButtonEntry = CustomButtonEntry(
id = it.id ?: "",
titleText = it.title ?: "",
icon = it.drawableId,
isVisible = it.isVisible ?: false,
isEnabled = it.isEnabled ?: false,
)
customButton1MutableStateFlow.value = customButtonEntry
}
if (buttonState.callScreenHeaderCustomButtonsState.size > 1) {
buttonState.callScreenHeaderCustomButtonsState[1].let {
val customButtonEntry = CustomButtonEntry(
id = it.id ?: "",
titleText = it.title ?: "",
icon = it.drawableId,
isVisible = it.isVisible ?: false,
isEnabled = it.isEnabled ?: false,
)
customButton2MutableStateFlow.value = customButtonEntry
}
}
}
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
fun updateIsOverlayDisplayed(callingStatus: CallingStatus) {
isOverlayDisplayedFlow.value = isOverlayDisplayed(callingStatus)
}
fun init(
callingStatus: CallingStatus,
numberOfRemoteParticipants: Int,
/* <CUSTOM_CALL_HEADER> */
callScreenInfoHeaderState: CallScreenInfoHeaderState,
/* </CUSTOM_CALL_HEADER> */
requestCallEndCallback: () -> Unit,
) {
timer = Timer()
/* <CUSTOM_CALL_HEADER> */
titleStateFlow = MutableStateFlow(callScreenInfoHeaderState.title)
subtitleStateFlow = MutableStateFlow(callScreenInfoHeaderState.subtitle)
/* </CUSTOM_CALL_HEADER> */
displayFloatingHeaderFlow = MutableStateFlow(false)
numberOfParticipantsFlow = MutableStateFlow(numberOfRemoteParticipants)
isOverlayDisplayedFlow = MutableStateFlow(isOverlayDisplayed(callingStatus))
this.requestCallEndCallback = requestCallEndCallback
}
fun switchFloatingHeader() {
if (displayFloatingHeaderFlow.value) {
displayFloatingHeaderFlow.value = false
timer.cancel()
return
}
displayFloatingHeaderFlow.value = true
timer = Timer()
timer.schedule(
object : TimerTask() {
override fun run() {
displayFloatingHeaderFlow.value = false
}
},
3000
)
displayFloatingHeaderFlow.value = !displayFloatingHeaderFlow.value
}
fun dismiss() {
if (displayFloatingHeaderFlow.value) {
displayFloatingHeaderFlow.value = false
timer.cancel()
return
}
displayFloatingHeaderFlow.value = false
}
private fun isOverlayDisplayed(callingStatus: CallingStatus) =
@ -112,4 +143,25 @@ internal class InfoHeaderViewModel(
fun requestCallEnd() {
requestCallEndCallback()
}
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
fun onCustomButtonClicked(context: Context, id: String) {
try {
val buttonViewData = updatableOptionsManager.getButton(id)
buttonViewData.onClickHandler?.handle(
createCustomButtonClickEvent(context, buttonViewData)
)
} catch (e: Exception) {
logger.error("Call screen control bar custom button onClick exception.", e)
}
}
data class CustomButtonEntry(
val id: String,
val titleText: String,
val icon: Int,
val isVisible: Boolean,
val isEnabled: Boolean,
)
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
}

Просмотреть файл

@ -91,7 +91,11 @@ internal class CallingViewModelFactory(
val floatingHeaderViewModel by lazy {
InfoHeaderViewModel(
enableMultitasking
enableMultitasking,
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
updatableOptionsManager,
logger,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
}

Просмотреть файл

@ -2,6 +2,7 @@ package com.azure.android.communication.ui.calling.presentation.manager
import com.azure.android.communication.ui.calling.configuration.CallCompositeConfiguration
import com.azure.android.communication.ui.calling.models.CallCompositeCustomButtonViewData
import com.azure.android.communication.ui.calling.models.setDrawableIdChangedEventHandler
import com.azure.android.communication.ui.calling.models.setEnabledChangedEventHandler
import com.azure.android.communication.ui.calling.models.setSubtitleChangedEventHandler
import com.azure.android.communication.ui.calling.models.setTitleChangedEventHandler
@ -16,7 +17,6 @@ internal class UpdatableOptionsManager(
private val store: Store<ReduxState>,
) {
fun start() {
/* <CUSTOM_CALL_HEADER> */
configuration.callScreenOptions?.headerViewData?.run {
setTitleChangedEventHandler {
store.dispatch(CallScreenInfoHeaderAction.UpdateTitle(it))
@ -25,7 +25,6 @@ internal class UpdatableOptionsManager(
store.dispatch(CallScreenInfoHeaderAction.UpdateSubtitle(it))
}
}
/* </CUSTOM_CALL_HEADER> */
configuration.callScreenOptions?.controlBarOptions?.run {
cameraButton?.setEnabledChangedEventHandler {
store.dispatch(ButtonViewDataAction.CallScreenCameraButtonIsEnabledUpdated(it))
@ -89,6 +88,9 @@ internal class UpdatableOptionsManager(
it.setVisibleChangedEventHandler { isVisible ->
store.dispatch(ButtonViewDataAction.CallScreenCustomButtonIsVisibleUpdated(it.id, isVisible))
}
it.setDrawableIdChangedEventHandler { drawableId ->
store.dispatch(ButtonViewDataAction.CallScreenCustomButtonIconUpdated(it.id, drawableId))
}
}
}
@ -112,6 +114,20 @@ internal class UpdatableOptionsManager(
store.dispatch(ButtonViewDataAction.SetupScreenAudioDeviceButtonIsVisibleUpdated(it))
}
}
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
configuration.callScreenOptions?.headerViewData?.customButtons?.forEach {
it.setEnabledChangedEventHandler { isEnabled ->
store.dispatch(ButtonViewDataAction.CallScreenHeaderCustomButtonIsEnabledUpdated(it.id, isEnabled))
}
it.setVisibleChangedEventHandler { isVisible ->
store.dispatch(ButtonViewDataAction.CallScreenHeaderCustomButtonIsVisibleUpdated(it.id, isVisible))
}
it.setDrawableIdChangedEventHandler { drawableId ->
store.dispatch(ButtonViewDataAction.CallScreenHeaderCustomButtonIconUpdated(it.id, drawableId))
}
}
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
}
fun getButton(id: String): CallCompositeCustomButtonViewData {
@ -120,6 +136,13 @@ internal class UpdatableOptionsManager(
?.let {
return it
}
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
configuration.callScreenOptions?.headerViewData?.customButtons
?.find { it.id == id }
?.let {
return it
}
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
throw IllegalArgumentException("Button with id $id not found")
}
}

Просмотреть файл

@ -31,6 +31,14 @@ internal sealed class ButtonViewDataAction : Action {
class CallScreenCustomButtonIsVisibleUpdated(val id: String, val isVisible: Boolean?) : ButtonViewDataAction()
class CallScreenCustomButtonTitleUpdated(val id: String, val title: String?) : ButtonViewDataAction()
class CallScreenCustomButtonIconUpdated(val id: String, val drawableId: Int) : ButtonViewDataAction()
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
class CallScreenHeaderCustomButtonIsEnabledUpdated(val id: String, val isEnabled: Boolean?) : ButtonViewDataAction()
class CallScreenHeaderCustomButtonIsVisibleUpdated(val id: String, val isVisible: Boolean?) : ButtonViewDataAction()
class CallScreenHeaderCustomButtonTitleUpdated(val id: String, val title: String?) : ButtonViewDataAction()
class CallScreenHeaderCustomButtonIconUpdated(val id: String, val drawableId: Int) : ButtonViewDataAction()
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
class SetupScreenCameraButtonIsEnabledUpdated(val isEnabled: Boolean?) : ButtonViewDataAction()
class SetupScreenCameraButtonIsVisibleUpdated(val isVisible: Boolean?) : ButtonViewDataAction()
class SetupScreenMicButtonIsEnabledUpdated(val isEnabled: Boolean?) : ButtonViewDataAction()

Просмотреть файл

@ -1,11 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* <CUSTOM_CALL_HEADER> */
package com.azure.android.communication.ui.calling.redux.action
internal sealed class CallScreenInfoHeaderAction : Action {
class UpdateTitle(var title: String?) : CallScreenInfoHeaderAction()
class UpdateSubtitle(var subtitle: String?) : CallScreenInfoHeaderAction()
}
/* </CUSTOM_CALL_HEADER> */

Просмотреть файл

@ -19,9 +19,7 @@ internal class AppStateReducer(
private val callDiagnosticsReducer: CallDiagnosticsReducer,
private val toastNotificationReducer: ToastNotificationReducer,
private val captionsReducer: CaptionsReducer,
/* <CUSTOM_CALL_HEADER> */
private val callScreenInformationHeaderReducer: CallScreenInformationHeaderReducer,
/* </CUSTOM_CALL_HEADER> */
private val buttonViewDataReducer: ButtonViewDataReducer,
/* <RTT_POC>
private val rttReducer: RttReducer,
@ -56,9 +54,7 @@ internal class AppStateReducer(
appState.callDiagnosticsState = callDiagnosticsReducer.reduce(state.callDiagnosticsState, action)
appState.toastNotificationState = toastNotificationReducer.reduce(state.toastNotificationState, action)
appState.captionsState = captionsReducer.reduce(state.captionsState, action)
/* <CUSTOM_CALL_HEADER> */
appState.callScreenInfoHeaderState = callScreenInformationHeaderReducer.reduce(state.callScreenInfoHeaderState, action)
/* </CUSTOM_CALL_HEADER> */
appState.buttonState = buttonViewDataReducer.reduce(state.buttonState, action)
/* <RTT_POC>
appState.rttState = rttReducer.reduce(state.rttState, action)

Просмотреть файл

@ -124,6 +124,52 @@ internal class ButtonViewDataReducerImpl : ButtonViewDataReducer {
}
)
}
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
is ButtonViewDataAction.CallScreenHeaderCustomButtonIsEnabledUpdated -> {
state.copy(
callScreenHeaderCustomButtonsState = state.callScreenHeaderCustomButtonsState.map {
if (it.id == action.id) {
it.copy(isEnabled = action.isEnabled)
} else {
it
}
}
)
}
is ButtonViewDataAction.CallScreenHeaderCustomButtonIsVisibleUpdated -> {
state.copy(
callScreenHeaderCustomButtonsState = state.callScreenHeaderCustomButtonsState.map {
if (it.id == action.id) {
it.copy(isVisible = action.isVisible)
} else {
it
}
}
)
}
is ButtonViewDataAction.CallScreenHeaderCustomButtonTitleUpdated -> {
state.copy(
callScreenHeaderCustomButtonsState = state.callScreenHeaderCustomButtonsState.map {
if (it.id == action.id) {
it.copy(title = action.title)
} else {
it
}
}
)
}
is ButtonViewDataAction.CallScreenHeaderCustomButtonIconUpdated -> {
state.copy(
callScreenHeaderCustomButtonsState = state.callScreenHeaderCustomButtonsState.map {
if (it.id == action.id) {
it.copy(drawableId = action.drawableId)
} else {
it
}
}
)
}
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
else -> state
}
}

Просмотреть файл

@ -1,6 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* <CUSTOM_CALL_HEADER> */
package com.azure.android.communication.ui.calling.redux.reducer
import com.azure.android.communication.ui.calling.redux.action.Action
@ -22,5 +21,3 @@ internal class CallScreenInformationHeaderReducerImpl : CallScreenInformationHea
}
}
}
/* </CUSTOM_CALL_HEADER> */

Просмотреть файл

@ -94,12 +94,10 @@ internal class AppReduxState(
override var captionsState: CaptionsState = CaptionsState(isCaptionsUIEnabled = showCaptionsUI)
/* <CUSTOM_CALL_HEADER> */
override var callScreenInfoHeaderState: CallScreenInfoHeaderState = CallScreenInfoHeaderState(
title = localOptions?.callScreenOptions?.headerViewData?.title,
subtitle = localOptions?.callScreenOptions?.headerViewData?.subtitle,
)
/* </CUSTOM_CALL_HEADER> */
/* <RTT_POC>
override var rttState = RttState()
@ -162,6 +160,17 @@ internal class AppReduxState(
title = it.title,
drawableId = it.drawableId,
)
} ?: emptyList(),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
callScreenHeaderCustomButtonsState = localOptions?.callScreenOptions?.headerViewData?.customButtons?.map {
CustomButtonState(
id = it.id,
isEnabled = it.isEnabled,
isVisible = it.isVisible,
title = it.title,
drawableId = it.drawableId,
)
} ?: emptyList()
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
}

Просмотреть файл

@ -30,4 +30,7 @@ internal data class ButtonState(
val reportIssueButton: DefaultButtonState? = null,
val callScreenCustomButtonsState: List<CustomButtonState> = emptyList(),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
val callScreenHeaderCustomButtonsState: List<CustomButtonState> = emptyList(),
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)

Просмотреть файл

@ -1,10 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* <CUSTOM_CALL_HEADER> */
package com.azure.android.communication.ui.calling.redux.state
internal data class CallScreenInfoHeaderState(
val title: String?,
val subtitle: String?,
)
/* </CUSTOM_CALL_HEADER> */

Просмотреть файл

@ -16,9 +16,7 @@ internal interface ReduxState {
var callDiagnosticsState: CallDiagnosticsState
var toastNotificationState: ToastNotificationState
val captionsState: CaptionsState
/* <CUSTOM_CALL_HEADER> */
val callScreenInfoHeaderState: CallScreenInfoHeaderState
/* </CUSTOM_CALL_HEADER> */
/* <RTT_POC>
var rttState: RttState
</RTT_POC> */

Просмотреть файл

@ -35,6 +35,7 @@ internal class BottomCellActionViewHolder(itemView: View) : BottomCellViewHolder
accessoryImageView.visibility =
if (bottomCellItem.isChecked == true) View.VISIBLE else View.INVISIBLE
avatarView.visibility = View.GONE
avatarViewForImage.visibility = View.GONE
icon.visibility = View.GONE
showMoreImageView.visibility = View.GONE
additionalText.visibility = View.GONE

Просмотреть файл

@ -3,6 +3,6 @@
Licensed under the MIT License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/azure_communication_ui_calling_color_on_primary" android:state_enabled="true" />
<item android:color="?attr/azure_communication_ui_calling_foreground_on_primary_color" android:state_enabled="true" />
<item android:color="@color/azure_communication_ui_calling_color_on_disabled" android:state_enabled="false" />
</selector>

Просмотреть файл

@ -4,8 +4,8 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:color="@color/azure_communication_ui_calling_color_primary" android:state_focused="true" android:state_enabled="true" app:azure_communication_ui_calling_state_setup_camera_on="false" />
<item android:color="@color/azure_communication_ui_calling_color_primary" android:state_focused="true" android:state_enabled="true" app:azure_communication_ui_calling_state_setup_camera_on="true" />
<item android:color="?attr/azure_communication_ui_calling_primary_color" android:state_focused="true" android:state_enabled="true" app:azure_communication_ui_calling_state_setup_camera_on="false" />
<item android:color="?attr/azure_communication_ui_calling_primary_color" android:state_focused="true" android:state_enabled="true" app:azure_communication_ui_calling_state_setup_camera_on="true" />
<item android:color="@color/azure_communication_ui_calling_color_on_surface_disabled" android:state_focused="true" android:state_enabled="false" />
<item android:color="@color/azure_communication_ui_calling_color_on_surface" android:state_enabled="true" app:azure_communication_ui_calling_state_setup_camera_on="false" />

Просмотреть файл

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) Microsoft Corporation. All rights reserved.
~ Licensed under the MIT License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false">
<shape>
<corners android:radius="@dimen/fluentui_button_corner_radius" />
<stroke
android:width="@dimen/fluentui_button_outlined_stroke_width"
android:color="?attr/azure_communication_ui_calling_primary_color" />
</shape>
</item>
<item android:state_pressed="true">
<shape>
<corners android:radius="@dimen/fluentui_button_corner_radius" />
<stroke
android:width="@dimen/fluentui_button_outlined_stroke_width"
android:color="?attr/azure_communication_ui_calling_primary_color" />
</shape>
</item>
<item>
<shape>
<corners android:radius="@dimen/fluentui_button_corner_radius" />
<stroke
android:width="@dimen/fluentui_button_outlined_stroke_width"
android:color="?attr/azure_communication_ui_calling_primary_color" />
</shape>
</item>
</selector>

Просмотреть файл

@ -11,6 +11,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M8.293 4.293c-0.39 0.39-0.39 1.024 0 1.414L14.586 12l-6.293 6.293c-0.39 0.39-0.39 1.024 0 1.414 0.39 0.39 1.024 0.39 1.414 0l7-7c0.39-0.39 0.39-1.024 0-1.414l-7-7c-0.39-0.39-1.024-0.39-1.414 0z" />
</vector>

Просмотреть файл

@ -9,7 +9,7 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M9.563 7.505l0.056 0.117 5.307 13.005c0.209 0.511-0.037 1.095-0.548 1.303-0.475 0.194-1.012-0.003-1.254-0.442l-0.05-0.106L11.693 18H5.407l-1.49 3.407c-0.207 0.47-0.73 0.702-1.208 0.555l-0.11-0.04c-0.47-0.206-0.702-0.73-0.556-1.208l0.04-0.11L7.778 7.6c0.336-0.77 1.394-0.795 1.786-0.094zM19 2c0.513 0 0.936 0.386 0.993 0.883L20 3v4h1c0.513 0 0.936 0.386 0.993 0.883L22 8c0 0.513-0.386 0.935-0.883 0.993L21 9h-1v7c0 0.513-0.386 0.936-0.883 0.993L19 17c-0.513 0-0.936-0.386-0.993-0.883L18 16V3c0-0.552 0.448-1 1-1zM8.66 10.567L6.283 16h4.595l-2.216-5.432zM11 2h5c0.513 0 0.936 0.386 0.993 0.883L17 3v2.975c0 2.209-1.79 4-4 4-0.552 0-1-0.448-1-1s0.448-1 1-1c1.054 0 1.918-0.816 1.995-1.85L15 5.974V4h-4c-0.552 0-1-0.448-1-1 0-0.513 0.386-0.936 0.883-0.993L11 2h5-5z"
tools:ignore="VectorPath" />
</vector>

Просмотреть файл

@ -9,7 +9,7 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M18.75 4C20.545 4 22 5.455 22 7.25v9.505c0 1.794-1.455 3.25-3.25 3.25H5.25c-1.795 0-3.25-1.456-3.25-3.25V7.25C2 5.517 3.357 4.1 5.066 4.005L5.25 4h13.5zm-8.128 4.598C8.213 7.225 5.5 8.854 5.5 12c0 3.143 2.715 4.775 5.12 3.407 0.36-0.205 0.487-0.663 0.282-1.023-0.205-0.36-0.663-0.486-1.023-0.281C8.484 14.896 7 14.005 7 12c0-2.006 1.48-2.896 2.878-2.098 0.36 0.205 0.818 0.08 1.024-0.28 0.205-0.36 0.08-0.818-0.28-1.024zm7.5 0C15.713 7.225 13 8.854 13 12c0 3.143 2.715 4.775 5.12 3.407 0.36-0.205 0.487-0.663 0.282-1.023-0.205-0.36-0.663-0.486-1.023-0.281C15.984 14.896 14.5 14.005 14.5 12c0-2.006 1.48-2.896 2.878-2.098 0.36 0.205 0.818 0.08 1.023-0.28 0.206-0.36 0.08-0.818-0.28-1.024z"
tools:ignore="VectorPath" />
</vector>

Просмотреть файл

@ -10,7 +10,7 @@
android:viewportHeight="12"
>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M2.089 2.216l0.058-0.07C2.32 1.974 2.589 1.955 2.784 2.09l0.07 0.058L6 5.293l3.146-3.147c0.196-0.195 0.512-0.195 0.707 0 0.196 0.196 0.196 0.512 0 0.708L6.708 6l3.147 3.146C10.027 9.32 10.046 9.59 9.91 9.784l-0.057 0.07C9.68 10.027 9.41 10.046 9.216 9.91l-0.07-0.057L6 6.707 2.853 9.854c-0.195 0.195-0.511 0.195-0.707 0-0.195-0.196-0.195-0.512 0-0.707L5.293 6 2.146 2.853C1.974 2.68 1.955 2.411 2.09 2.216l0.058-0.07-0.058 0.07z"
/>
</vector>

Просмотреть файл

@ -10,7 +10,7 @@
android:viewportHeight="6"
>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M5.25,3C5.25,4.2426 4.2426,5.25 3,5.25C1.7574,5.25 0.75,4.2426 0.75,3C0.75,1.7574 1.7574,0.75 3,0.75C4.2426,0.75 5.25,1.7574 5.25,3ZM13.25,3C13.25,4.2426 12.2426,5.25 11,5.25C9.7574,5.25 8.75,4.2426 8.75,3C8.75,1.7574 9.7574,0.75 11,0.75C12.2426,0.75 13.25,1.7574 13.25,3ZM19,5.25C20.2426,5.25 21.25,4.2426 21.25,3C21.25,1.7574 20.2426,0.75 19,0.75C17.7574,0.75 16.75,1.7574 16.75,3C16.75,4.2426 17.7574,5.25 19,5.25Z"
/>
</vector>

Просмотреть файл

@ -9,7 +9,7 @@
android:viewportHeight="24"
>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M3.28 2.22c-0.293-0.293-0.767-0.293-1.06 0-0.293 0.293-0.293 0.767 0 1.06L8 9.06V12c0 2.21 1.79 4 4 4 0.834 0 1.607-0.255 2.248-0.691l1.146 1.146C14.518 17.11 13.429 17.5 12.25 17.5h-0.5l-0.216-0.004C8.734 17.382 6.5 15.077 6.5 12.25v-0.5l-0.007-0.102C6.443 11.282 6.13 11 5.75 11 5.336 11 5 11.336 5 11.75v0.5l0.004 0.236c0.119 3.452 2.83 6.246 6.246 6.496v2.268l0.007 0.102C11.307 21.718 11.62 22 12 22c0.414 0 0.75-0.336 0.75-0.75l0.001-2.268c1.399-0.103 2.68-0.632 3.712-1.458l4.256 4.256c0.293 0.293 0.768 0.293 1.061 0 0.293-0.292 0.293-0.767 0-1.06L3.28 2.22zm13.916 11.794l1.146 1.146C18.764 14.28 19 13.292 19 12.25v-0.5l-0.007-0.102C18.943 11.282 18.63 11 18.25 11c-0.414 0-0.75 0.336-0.75 0.75v0.5l-0.004 0.216c-0.022 0.542-0.126 1.062-0.3 1.548zM8.138 4.956l7.792 7.792C15.976 12.506 16 12.256 16 12V6c0-2.21-1.79-4-4-4-1.848 0-3.403 1.253-3.862 2.956z"
/>
</vector>

Просмотреть файл

@ -9,7 +9,7 @@
android:viewportHeight="24"
>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M18.25 11c0.38 0 0.694 0.282 0.743 0.648L19 11.75v0.5c0 3.56-2.755 6.475-6.249 6.732L12.75 21.25c0 0.414-0.336 0.75-0.75 0.75-0.38 0-0.694-0.282-0.743-0.648L11.25 21.25v-2.268c-3.417-0.25-6.127-3.044-6.246-6.496L5 12.25v-0.5C5 11.336 5.336 11 5.75 11c0.38 0 0.694 0.282 0.743 0.648L6.5 11.75v0.5c0 2.827 2.234 5.132 5.034 5.246L11.75 17.5h0.5c2.827 0 5.132-2.234 5.246-5.034L17.5 12.25v-0.5c0-0.414 0.336-0.75 0.75-0.75zM12 2c2.21 0 4 1.79 4 4v6c0 2.21-1.79 4-4 4s-4-1.79-4-4V6c0-2.21 1.79-4 4-4z"
android:strokeWidth="1"
/>

Просмотреть файл

@ -10,7 +10,7 @@
android:viewportHeight="24"
>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M4 13.999L13 14c1.054 0 1.918 0.816 1.995 1.85L15 16v1.5C14.999 21 11.284 22 8.5 22c-2.722 0-6.335-0.956-6.495-4.27L2 17.5v-1.501c0-1.054 0.816-1.918 1.85-1.995L4 14zM15.22 14H20c1.054 0 1.918 0.816 1.994 1.85L22 16v1c-0.001 3.062-2.858 4-5 4-0.68 0-1.431-0.096-2.14-0.322 0.336-0.386 0.607-0.827 0.802-1.327C16.205 19.476 16.715 19.5 17 19.5l0.267-0.006c0.985-0.043 3.086-0.363 3.226-2.289L20.5 17v-1c0-0.245-0.178-0.45-0.41-0.492L20 15.5h-4.051c-0.084-0.501-0.294-0.957-0.595-1.34L15.22 14H20h-4.78zM4 15.499l-0.1 0.01c-0.125 0.025-0.21 0.093-0.254 0.136-0.043 0.044-0.11 0.128-0.136 0.253L3.5 15.999V17.5c0 1.009 0.45 1.722 1.417 2.242 0.826 0.445 2.003 0.714 3.266 0.753L8.5 20.5l0.317-0.005c1.263-0.039 2.439-0.308 3.266-0.753 0.906-0.488 1.359-1.145 1.412-2.057l0.005-0.186V16c0-0.245-0.178-0.45-0.41-0.492L13 15.5l-9-0.001zM8.5 3C10.985 3 13 5.015 13 7.5S10.985 12 8.5 12 4 9.985 4 7.5 6.015 3 8.5 3zm9 2C19.433 5 21 6.567 21 8.5S19.433 12 17.5 12 14 10.433 14 8.5 15.567 5 17.5 5zm-9-0.5c-1.654 0-3 1.346-3 3s1.346 3 3 3 3-1.346 3-3-1.346-3-3-3zm9 2c-1.103 0-2 0.897-2 2s0.897 2 2 2 2-0.897 2-2-0.897-2-2-2z"
/>
</vector>

Просмотреть файл

@ -9,7 +9,7 @@
android:viewportHeight="24"
>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M15 4.25v15.496c0 1.078-1.274 1.65-2.08 0.934l-4.492-3.994c-0.137-0.122-0.315-0.19-0.498-0.19H4.25c-1.243 0-2.25-1.007-2.25-2.25V9.75C2 8.507 3.007 7.5 4.25 7.5h3.68c0.183 0 0.36-0.068 0.498-0.19l4.491-3.993C13.726 2.599 15 3.17 15 4.25zm3.992 1.647c0.332-0.246 0.802-0.176 1.049 0.157C21.27 7.716 22 9.774 22 12c0 2.226-0.728 4.284-1.96 5.946-0.246 0.333-0.716 0.403-1.048 0.157-0.333-0.247-0.403-0.716-0.157-1.05C19.881 15.642 20.5 13.894 20.5 12c0-1.894-0.619-3.641-1.665-5.054-0.246-0.332-0.176-0.802 0.157-1.049zM17.143 8.37c0.364-0.197 0.82-0.061 1.017 0.303C18.696 9.662 19 10.797 19 12c0 1.203-0.304 2.338-0.84 3.328-0.198 0.364-0.653 0.5-1.017 0.303-0.364-0.197-0.5-0.653-0.303-1.017 0.42-0.777 0.66-1.666 0.66-2.614s-0.24-1.837-0.66-2.614c-0.197-0.364-0.061-0.82 0.303-1.017z"
/>

Просмотреть файл

@ -9,11 +9,11 @@
android:viewportHeight="24"
>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M15 4.25c0-1.079-1.274-1.65-2.08-0.934L8.427 7.309C8.29 7.431 8.113 7.5 7.93 7.5H4.25C3.007 7.499 2 8.506 2 9.749v4.497c0 1.243 1.007 2.25 2.25 2.25h3.68c0.183 0 0.36 0.068 0.498 0.19l4.491 3.994C13.725 21.396 15 20.824 15 19.746V4.25zM9.425 8.43L13.5 4.807v14.382l-4.075-3.624C9.013 15.2 8.48 14.996 7.93 14.996H4.25c-0.414 0-0.75-0.335-0.75-0.75V9.75C3.5 9.335 3.836 9 4.25 9h3.68c0.55 0 1.083-0.203 1.495-0.569zm9.567-2.533c0.332-0.246 0.802-0.176 1.049 0.157C21.27 7.716 22 9.774 22 12c0 2.226-0.728 4.284-1.96 5.946-0.246 0.333-0.716 0.403-1.048 0.157-0.333-0.247-0.403-0.716-0.157-1.05C19.881 15.642 20.5 13.894 20.5 12c0-1.894-0.619-3.641-1.665-5.054-0.246-0.332-0.176-0.802 0.157-1.049z"
/>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M17.143 8.37c0.364-0.198 0.82-0.062 1.017 0.302C18.696 9.662 19 10.797 19 12c0 1.203-0.304 2.338-0.84 3.328-0.198 0.364-0.653 0.5-1.017 0.303-0.364-0.197-0.5-0.653-0.303-1.017 0.42-0.777 0.66-1.666 0.66-2.614s-0.24-1.837-0.66-2.614c-0.197-0.364-0.061-0.82 0.303-1.017z"
/>
</vector>

Просмотреть файл

@ -9,7 +9,7 @@
android:viewportHeight="24"
>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M14.7041,3.4425C14.8952,3.6682 15,3.9543 15,4.25V19.7517C15,20.442 14.4404,21.0017 13.75,21.0017C13.4542,21.0017 13.168,20.8968 12.9423,20.7056L7.9751,16.4999H4.25C3.0074,16.4999 2,15.4925 2,14.2499V9.7499C2,8.5072 3.0074,7.4998 4.25,7.4998H7.9752L12.9425,3.2959C13.4694,2.8499 14.2582,2.9155 14.7041,3.4425ZM13.5,4.7891L8.5248,8.9999H4.25C3.8358,8.9999 3.5,9.3356 3.5,9.7499V14.2499C3.5,14.6641 3.8358,14.9999 4.25,14.9999H8.5249L13.5,19.2124V4.7891ZM17.5,9.8956V6.7498C17.5,6.1031 18.2521,5.7749 18.725,6.1688L18.8011,6.2411L21.8011,9.4911C22.0679,9.7802 22.063,10.2201 21.8063,10.503L21.7301,10.5761L20.0221,11.9991L21.7304,13.4239C22.0323,13.6757 22.0846,14.1123 21.8672,14.4261L21.8012,14.5084L18.8012,17.7599C18.3626,18.2353 17.5872,17.9663 17.5068,17.3561L17.5,17.2513V14.1005L17.2334,14.3226C16.9152,14.5877 16.4423,14.5447 16.1771,14.2265C15.9361,13.9372 15.9497,13.52 16.1933,13.2474L16.2732,13.1702L17.5,12.1481V11.8488L16.2729,10.8254C15.9549,10.5601 15.9121,10.0871 16.1774,9.769C16.4186,9.4799 16.8313,9.4182 17.1434,9.6087L17.2337,9.6735L17.5,9.8956V6.7498V9.8956ZM19,13.0999V15.3325L20.1641,14.0708L19,13.0999ZM19,8.6681V10.8983L20.1637,9.9288L19,8.6681Z"
/>
</vector>

Просмотреть файл

@ -9,7 +9,7 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M20.392 0.466c0.363-0.2 0.819-0.066 1.018 0.297C22.424 2.615 23 4.741 23 7c0 2.258-0.576 4.384-1.59 6.236-0.2 0.364-0.655 0.497-1.018 0.298-0.364-0.2-0.497-0.655-0.298-1.018C20.991 10.879 21.501 9 21.501 7s-0.51-3.88-1.407-5.516c-0.199-0.363-0.066-0.82 0.298-1.018zM17.29 3.06c0.38-0.164 0.822 0.013 0.985 0.393 0.467 1.09 0.726 2.288 0.726 3.546 0 1.257-0.259 2.456-0.726 3.545-0.163 0.38-0.604 0.557-0.985 0.394-0.38-0.164-0.557-0.604-0.393-0.985C17.285 9.048 17.5 8.05 17.5 7c0-1.05-0.216-2.049-0.604-2.954-0.164-0.381 0.013-0.822 0.393-0.985zm0.713 13.188c0-1.242-1.006-2.25-2.248-2.25H4.252c-1.242 0-2.25 1.008-2.25 2.25v0.92c0 0.572 0.18 1.13 0.511 1.595C4.056 20.93 6.58 22.001 10 22.001s5.945-1.072 7.49-3.235c0.334-0.467 0.513-1.026 0.513-1.599v-0.918zM15 7.004c0-2.761-2.238-5-5-5-2.761 0-5 2.239-5 5 0 2.762 2.239 5 5 5 2.762 0 5-2.238 5-5z"
tools:ignore="VectorPath" />
</vector>

Просмотреть файл

@ -9,7 +9,7 @@
android:viewportHeight="24"
>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M16 16.25c0 1.795-1.455 3.25-3.25 3.25h-7.5C3.455 19.5 2 18.045 2 16.25v-8.5C2 5.955 3.455 4.5 5.25 4.5h7.5C14.545 4.5 16 5.955 16 7.75v8.5zm5.762-10.357C21.916 6.074 22 6.303 22 6.541v10.918c0 0.552-0.448 1-1 1-0.237 0-0.467-0.085-0.648-0.238L17 15.37V8.628l3.352-2.849c0.421-0.358 1.052-0.306 1.41 0.114z"
android:strokeWidth="1"
/>

Просмотреть файл

@ -9,7 +9,7 @@
android:viewportHeight="24"
>
<path
android:fillColor="@color/azure_communication_ui_calling_color_primary"
android:fillColor="?attr/azure_communication_ui_calling_primary_color"
android:pathData="M3.28 2.22c-0.293-0.293-0.767-0.293-1.06 0-0.293 0.293-0.293 0.767 0 1.06l1.567 1.567C2.727 5.383 2 6.481 2 7.75v8.5c0 1.795 1.455 3.25 3.25 3.25h7.5c1.544 0 2.837-1.077 3.168-2.521l4.801 4.802c0.293 0.292 0.768 0.292 1.061 0 0.293-0.293 0.293-0.768 0-1.061L3.28 2.22zM17 13.818l4.504 4.505C21.801 18.149 22 17.827 22 17.459V6.54c0-0.237-0.084-0.467-0.238-0.648-0.358-0.42-0.989-0.472-1.41-0.114L17 8.628v5.19zM7.682 4.5L16 12.818V7.75c0-1.795-1.455-3.25-3.25-3.25H7.682z"
/>
</vector>

Просмотреть файл

@ -28,7 +28,7 @@
android:layout_height="32dp"
android:layout_marginEnd="8dp"
android:contentDescription="@string/azure_communication_ui_calling_starting_captions"
android:indeterminateTint="@color/azure_communication_ui_calling_color_primary" />
android:indeterminateTint="?attr/azure_communication_ui_calling_primary_color" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/AzureCommunicationUICalling.ButtonText"

Просмотреть файл

@ -158,8 +158,8 @@
android:id="@+id/azure_communication_ui_setup_settings_button"
android:layout_width="142dp"
android:layout_height="48dp"
android:textColor="@color/azure_communication_ui_calling_color_primary"
android:background="@drawable/button_outlined"
android:textColor="?attr/azure_communication_ui_calling_primary_color"
android:background="@drawable/azure_communication_ui_calling_button_outline"
android:text="@string/azure_communication_ui_calling_setup_view_go_to_settings" />
</com.azure.android.communication.ui.calling.presentation.fragment.setup.components.PermissionWarningView>
@ -298,7 +298,7 @@
android:layout_width="24dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:indeterminateTint="@color/azure_communication_ui_calling_color_primary"
android:indeterminateTint="?attr/azure_communication_ui_calling_primary_color"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/azure_communication_ui_setup_start_call_joining_text"
app:layout_constraintEnd_toStartOf="@+id/azure_communication_ui_setup_start_call_joining_text"

Просмотреть файл

@ -68,7 +68,7 @@
android:alpha="1"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="@color/azure_communication_ui_calling_color_white"
android:textColor="?attr/azure_communication_ui_calling_foreground_on_primary_color"
app:backgroundTint="@color/azure_communication_ui_calling_primary_selector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/azure_communication_ui_calling_lobby_close_button"

Просмотреть файл

@ -46,7 +46,7 @@
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/azure_communication_ui_call_bottom_drawer_button"
app:layout_constraintEnd_toStartOf="@+id/azure_communication_ui_call_header_custom_button_1"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/azure_communication_ui_call_header_back_button"
app:layout_constraintTop_toTopOf="parent"
@ -68,6 +68,33 @@
android:textColor="@color/azure_communication_ui_calling_color_white" />
</LinearLayout>
<ImageButton
android:id="@+id/azure_communication_ui_call_header_custom_button_1"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:backgroundTint="@color/azure_communication_ui_calling_color_button_background_transparent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/azure_communication_ui_call_header_custom_button_2"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/azure_communication_ui_calling_ic_fluent_people_24_selector"
android:visibility="gone"
/>
<ImageButton
android:id="@+id/azure_communication_ui_call_header_custom_button_2"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:backgroundTint="@color/azure_communication_ui_calling_color_button_background_transparent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/azure_communication_ui_call_bottom_drawer_button"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/azure_communication_ui_calling_ic_fluent_people_24_selector"
android:visibility="gone"
/>
<ImageButton
android:id="@+id/azure_communication_ui_call_bottom_drawer_button"
android:layout_width="24dp"

Просмотреть файл

@ -52,7 +52,7 @@
android:focusable="true"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="@color/azure_communication_ui_calling_color_on_primary"
android:textColor="?attr/azure_communication_ui_calling_foreground_on_primary_color"
app:backgroundTint="@color/azure_communication_ui_calling_primary_selector"
/>

Просмотреть файл

@ -28,7 +28,7 @@
android:layout_height="32dp"
android:layout_marginEnd="8dp"
android:contentDescription="@string/azure_communication_ui_calling_starting_captions"
android:indeterminateTint="@color/azure_communication_ui_calling_color_primary" />
android:indeterminateTint="?attr/azure_communication_ui_calling_primary_color" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/AzureCommunicationUICalling.ButtonText"

Просмотреть файл

@ -25,7 +25,7 @@
android:layout_height="32dp"
android:layout_marginEnd="8dp"
android:contentDescription="@string/azure_communication_ui_calling_setup_view_button_connecting_call"
android:indeterminateTint="@color/azure_communication_ui_calling_color_primary"
android:indeterminateTint="?attr/azure_communication_ui_calling_primary_color"
/>
<androidx.appcompat.widget.AppCompatTextView

Просмотреть файл

@ -114,8 +114,8 @@
android:id="@+id/azure_communication_ui_setup_settings_button"
android:layout_width="142dp"
android:layout_height="48dp"
android:textColor="@color/azure_communication_ui_calling_color_primary"
android:background="@drawable/button_outlined"
android:textColor="?attr/azure_communication_ui_calling_primary_color"
android:background="@drawable/azure_communication_ui_calling_button_outline"
android:text="@string/azure_communication_ui_calling_setup_view_go_to_settings" />
@ -255,7 +255,7 @@
android:layout_width="24dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:indeterminateTint="@color/azure_communication_ui_calling_color_primary"
android:indeterminateTint="?attr/azure_communication_ui_calling_primary_color"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/azure_communication_ui_setup_start_call_joining_text"
app:layout_constraintEnd_toStartOf="@+id/azure_communication_ui_setup_start_call_joining_text"

Просмотреть файл

@ -74,7 +74,7 @@
android:alpha="1"
android:textAlignment="center"
android:textAllCaps="false"
android:textColor="@color/azure_communication_ui_calling_color_white"
android:textColor="?attr/azure_communication_ui_calling_foreground_on_primary_color"
app:backgroundTint="@color/azure_communication_ui_calling_primary_selector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/azure_communication_ui_calling_lobby_close_button"

Просмотреть файл

@ -8,6 +8,7 @@
These attributes represent the brand colors.
-->
<attr name="azure_communication_ui_calling_primary_color" type="color|reference" />
<attr name="azure_communication_ui_calling_foreground_on_primary_color" type= "color|reference"/>
<attr name="azure_communication_ui_calling_primary_color_tint10" type="color|reference" />
<attr name="azure_communication_ui_calling_primary_color_tint20" type="color|reference" />
<attr name="azure_communication_ui_calling_primary_color_tint30" type="color|reference" />

Просмотреть файл

@ -19,6 +19,9 @@
<item name="azure_communication_ui_calling_primary_color">
@color/fluentui_communication_blue
</item>
<item name="azure_communication_ui_calling_foreground_on_primary_color">
@color/azure_communication_ui_calling_color_on_primary
</item>
<item name="azure_communication_ui_calling_primary_color_tint10">#2B88D8</item>
<item name="azure_communication_ui_calling_primary_color_tint20">
@color/fluentui_communication_tint_20

Просмотреть файл

@ -5,6 +5,7 @@
<resources>
<public name="AzureCommunicationUICalling.Theme" type="style" />
<public name="azure_communication_ui_calling_primary_color" type="attr" />
<public name="azure_communication_ui_calling_foreground_on_primary_color" type="attr" />
<public name="azure_communication_ui_calling_primary_color_tint10" type="attr" />
<public name="azure_communication_ui_calling_primary_color_tint20" type="attr" />
<public name="azure_communication_ui_calling_primary_color_tint30" type="attr" />

Просмотреть файл

@ -9,9 +9,7 @@ import com.azure.android.communication.ui.calling.configuration.CallCompositeCon
import com.azure.android.communication.ui.calling.configuration.RemoteParticipantsConfigurationHandler
import com.azure.android.communication.ui.calling.handlers.RemoteParticipantHandler
import com.azure.android.communication.ui.calling.models.CallCompositeRemoteParticipantJoinedEvent
/* <CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.calling.models.CallCompositeRemoteParticipantLeftEvent
/* </CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.calling.models.ParticipantInfoModel
import com.azure.android.communication.ui.calling.models.StreamType
import com.azure.android.communication.ui.calling.models.VideoStreamModel
@ -738,7 +736,6 @@ internal class RemoteParticipantHandlerUnitTests : ACSBaseTestCoroutine() {
}
}
/* <CUSTOM_CALL_HEADER> */
@Test
fun remoteParticipantHandler_start_onStateChangeWithRemoteParticipantRemoved_then_eventIsFiredToOnce() {
runScopedTest {
@ -912,5 +909,4 @@ internal class RemoteParticipantHandlerUnitTests : ACSBaseTestCoroutine() {
job.cancel()
}
}
/* </CUSTOM_CALL_HEADER> */
}

Просмотреть файл

@ -444,9 +444,10 @@ internal class CallingViewModelUnitTest : ACSBaseTestCoroutine() {
verify(mockParticipantGridViewModel, times(1)).update(any(), any(), any(), any(), any())
verify(mockFloatingHeaderViewModel, times(1)).update(
any(),
/* <CUSTOM_CALL_HEADER> */
any()
/* </CUSTOM_CALL_HEADER> */
any(),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
any(),
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
verify(mockParticipantListViewModel, times(1)).update(any(), any(), any(), any(), any())
verify(mockBannerViewModel, times(1)).update(any(), any())
@ -573,9 +574,10 @@ internal class CallingViewModelUnitTest : ACSBaseTestCoroutine() {
verify(mockParticipantGridViewModel, times(1)).update(any(), any(), any(), any(), any())
verify(mockFloatingHeaderViewModel, times(1)).update(
any(),
/* <CUSTOM_CALL_HEADER> */
any()
/* </CUSTOM_CALL_HEADER> */
any(),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
any(),
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
verify(mockParticipantListViewModel, times(1)).update(any(), any(), any(), any(), any())
verify(mockBannerViewModel, times(1)).update(any(), any())
@ -701,9 +703,10 @@ internal class CallingViewModelUnitTest : ACSBaseTestCoroutine() {
verify(mockParticipantGridViewModel, times(0)).update(any(), any(), any(), any(), any())
verify(mockFloatingHeaderViewModel, times(0)).update(
any(),
/* <CUSTOM_CALL_HEADER> */
any()
/* </CUSTOM_CALL_HEADER> */
any(),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
any(),
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
verify(mockParticipantListViewModel, times(0)).update(any(), any(), any(), any(), any())
verify(mockBannerViewModel, times(0)).update(any(), any())
@ -1365,9 +1368,10 @@ internal class CallingViewModelUnitTest : ACSBaseTestCoroutine() {
)
verify(mockFloatingHeaderViewModel, times(1)).update(
argThat { count -> count == expectedParticipantCountOnFloatingHeader },
/* <CUSTOM_CALL_HEADER> */
any()
/* </CUSTOM_CALL_HEADER> */
any(),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
any(),
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
verify(
mockParticipantListViewModel,

Просмотреть файл

@ -6,9 +6,7 @@ package com.azure.android.communication.ui.calling.presentation.fragment.calling
import com.azure.android.communication.ui.calling.ACSBaseTestCoroutine
import com.azure.android.communication.ui.calling.models.ParticipantInfoModel
import com.azure.android.communication.ui.calling.redux.state.AppReduxState
/* <CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.calling.redux.state.CallScreenInfoHeaderState
/* </CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.calling.redux.state.CallingState
import com.azure.android.communication.ui.calling.redux.state.CallingStatus
import com.azure.android.communication.ui.calling.redux.state.RemoteParticipantsState
@ -56,13 +54,19 @@ internal class InfoHeaderViewModelUnitTest : ACSBaseTestCoroutine() {
isTranscribing = false
)
val floatingHeaderViewModel = InfoHeaderViewModel(false)
val floatingHeaderViewModel = InfoHeaderViewModel(
false,
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
mock(), mock()
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
floatingHeaderViewModel.init(
appState.callState.callingStatus,
expectedParticipantMap.count(),
/* <CUSTOM_CALL_HEADER> */
CallScreenInfoHeaderState(null, null)
/* </CUSTOM_CALL_HEADER> */
CallScreenInfoHeaderState(null, null),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
appState.buttonState,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
) { }
val resultListFromNumberOfParticipantsFlow =
@ -76,9 +80,10 @@ internal class InfoHeaderViewModelUnitTest : ACSBaseTestCoroutine() {
// act
floatingHeaderViewModel.update(
expectedParticipantMap.count(),
/* <CUSTOM_CALL_HEADER> */
CallScreenInfoHeaderState(null, null)
/* </CUSTOM_CALL_HEADER> */
CallScreenInfoHeaderState(null, null),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
appState.buttonState,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
// assert
@ -123,13 +128,19 @@ internal class InfoHeaderViewModelUnitTest : ACSBaseTestCoroutine() {
isTranscribing = false
)
val floatingHeaderViewModel = InfoHeaderViewModel(false)
val floatingHeaderViewModel = InfoHeaderViewModel(
false,
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
mock(), mock()
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
floatingHeaderViewModel.init(
appState.callState.callingStatus,
expectedParticipantMap.count(),
/* <CUSTOM_CALL_HEADER> */
CallScreenInfoHeaderState(null, null)
/* </CUSTOM_CALL_HEADER> */
CallScreenInfoHeaderState(null, null),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
appState.buttonState,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
) {}
val resultListFromIsLobbyOverlayDisplayedFlow =
@ -159,7 +170,6 @@ internal class InfoHeaderViewModelUnitTest : ACSBaseTestCoroutine() {
}
}
/* <CUSTOM_CALL_HEADER> */
@ExperimentalCoroutinesApi
@Test
fun floatingHeaderViewModel_update_then_displayTitleAndSubtitle() {
@ -190,35 +200,36 @@ internal class InfoHeaderViewModelUnitTest : ACSBaseTestCoroutine() {
isRecording = false,
isTranscribing = false
)
/* <CUSTOM_CALL_HEADER> */
val title = "title"
val subtitle = "subtitle"
/* </CUSTOM_CALL_HEADER> */
val floatingHeaderViewModel = InfoHeaderViewModel(false)
val floatingHeaderViewModel = InfoHeaderViewModel(
false,
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
mock(), mock()
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
floatingHeaderViewModel.init(
appState.callState.callingStatus,
expectedParticipantMap.count(),
/* <CUSTOM_CALL_HEADER> */
CallScreenInfoHeaderState(title, subtitle)
/* </CUSTOM_CALL_HEADER> */
CallScreenInfoHeaderState(title, subtitle),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
appState.buttonState,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
) { }
val resultListFromNumberOfParticipantsFlow =
mutableListOf<Int>()
/* <CUSTOM_CALL_HEADER> */
val resultListFromTitleStateFlow =
mutableListOf<String?>()
val resultListFromSubtitleStateFlow =
mutableListOf<String?>()
/* </CUSTOM_CALL_HEADER> */
val flowJobParticipant = launch {
floatingHeaderViewModel.getNumberOfParticipantsFlow()
.toList(resultListFromNumberOfParticipantsFlow)
}
/* <CUSTOM_CALL_HEADER> */
val flowJobTitle = launch {
floatingHeaderViewModel.getTitleStateFlow()
.toList(resultListFromTitleStateFlow)
@ -228,14 +239,14 @@ internal class InfoHeaderViewModelUnitTest : ACSBaseTestCoroutine() {
floatingHeaderViewModel.getSubtitleStateFlow()
.toList(resultListFromSubtitleStateFlow)
}
/* </CUSTOM_CALL_HEADER> */
// act
floatingHeaderViewModel.update(
expectedParticipantMap.count(),
/* <CUSTOM_CALL_HEADER> */
CallScreenInfoHeaderState(null, null)
/* </CUSTOM_CALL_HEADER> */
CallScreenInfoHeaderState(null, null),
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
appState.buttonState,
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
)
// assert
@ -244,7 +255,6 @@ internal class InfoHeaderViewModelUnitTest : ACSBaseTestCoroutine() {
resultListFromNumberOfParticipantsFlow[0]
)
/* <CUSTOM_CALL_HEADER> */
Assert.assertEquals(
title,
resultListFromTitleStateFlow[0]
@ -254,14 +264,119 @@ internal class InfoHeaderViewModelUnitTest : ACSBaseTestCoroutine() {
subtitle,
resultListFromSubtitleStateFlow[0]
)
/* </CUSTOM_CALL_HEADER> */
flowJobParticipant.cancel()
/* <CUSTOM_CALL_HEADER> */
flowJobTitle.cancel()
flowJobSubtitle.cancel()
/* </CUSTOM_CALL_HEADER> */
}
}
/* </CUSTOM_CALL_HEADER> */
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
@ExperimentalCoroutinesApi
@Test
fun floatingHeaderViewModel_update_then_displayCustomButtons() {
runScopedTest {
val appState = AppReduxState("", false, false)
val expectedParticipantMap: Map<String, ParticipantInfoModel> = mapOf()
val timestamp: Number = System.currentTimeMillis()
appState.remoteParticipantState = RemoteParticipantsState(
expectedParticipantMap,
timestamp,
listOf(),
0,
lobbyErrorCode = null,
totalParticipantCount = 0,
)
appState.callState = CallingState(
CallingStatus.CONNECTED,
joinCallIsRequested = false,
isRecording = false,
isTranscribing = false
)
appState.buttonState = ButtonState(callScreenHeaderCustomButtonsState = listOf())
val title = "title"
val subtitle = "subtitle"
val floatingHeaderViewModel = InfoHeaderViewModel(
false,
mock(), mock()
)
floatingHeaderViewModel.init(
appState.callState.callingStatus,
expectedParticipantMap.count(),
CallScreenInfoHeaderState(title, subtitle),
appState.buttonState,
) { }
val customButton1StateFlow =
mutableListOf<InfoHeaderViewModel.CustomButtonEntry?>()
val customButton2StateFlow =
mutableListOf<InfoHeaderViewModel.CustomButtonEntry?>()
val flowButton1 = launch {
floatingHeaderViewModel.getCustomButton1StateFlow()
.toList(customButton1StateFlow)
}
val flowButton2 = launch {
floatingHeaderViewModel.getCustomButton2StateFlow()
.toList(customButton2StateFlow)
}
// act
val button1 = CustomButtonState(
id = "id1",
isEnabled = true,
isVisible = true,
title = "title1",
drawableId = 1
)
val button2 = CustomButtonState(
id = "id2",
isEnabled = true,
isVisible = true,
title = "title2",
drawableId = 2
)
val buttonState1 = ButtonState(callScreenHeaderCustomButtonsState = listOf(button1))
floatingHeaderViewModel.update(
expectedParticipantMap.count(),
CallScreenInfoHeaderState(null, null),
buttonState1,
)
Assert.assertEquals(2, customButton1StateFlow.size)
Assert.assertEquals(1, customButton2StateFlow.size)
Assert.assertEquals(button1.id, customButton1StateFlow[1]?.id)
Assert.assertEquals(button1.title, customButton1StateFlow[1]?.titleText)
Assert.assertEquals(button1.drawableId, customButton1StateFlow[1]?.icon)
Assert.assertEquals(button1.isEnabled, customButton1StateFlow[1]?.isEnabled)
Assert.assertEquals(button1.isVisible, customButton1StateFlow[1]?.isVisible)
val buttonState2 = ButtonState(callScreenHeaderCustomButtonsState = listOf(button1, button2))
// act
floatingHeaderViewModel.update(
expectedParticipantMap.count(),
CallScreenInfoHeaderState(null, null),
buttonState2,
)
Assert.assertEquals(2, customButton1StateFlow.size)
Assert.assertEquals(2, customButton2StateFlow.size)
Assert.assertEquals(button2.id, customButton2StateFlow[1]?.id)
Assert.assertEquals(button2.title, customButton2StateFlow[1]?.titleText)
Assert.assertEquals(button2.drawableId, customButton2StateFlow[1]?.icon)
Assert.assertEquals(button2.isEnabled, customButton2StateFlow[1]?.isEnabled)
Assert.assertEquals(button2.isVisible, customButton2StateFlow[1]?.isVisible)
flowButton1.cancel()
flowButton2.cancel()
}
}
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
}

Просмотреть файл

@ -1,6 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* <CUSTOM_CALL_HEADER> */
package com.azure.android.communication.ui.calling.presentation.manager
import com.azure.android.communication.ui.calling.ACSBaseTestCoroutine
@ -80,4 +79,3 @@ internal class CallScreenInfoHeaderManagerTests : ACSBaseTestCoroutine() {
)
}
}
/* </CUSTOM_CALL_HEADER> */

Просмотреть файл

@ -71,10 +71,8 @@ internal class AppReduxStateReducerUnitTest {
@Mock
private lateinit var mockCaptionsReducer: CaptionsReducerImpl
/* <CUSTOM_CALL_HEADER> */
@Mock
private lateinit var mockCallScreenInformationHeaderReducer: CallScreenInformationHeaderReducerImpl
/* </CUSTOM_CALL_HEADER> */
@Mock
private lateinit var buttonOptionsReducer: ButtonViewDataReducerImpl
@ -97,9 +95,7 @@ internal class AppReduxStateReducerUnitTest {
mockCallDiagnosticsReducerImpl,
toastNotificationReducerImpl,
mockCaptionsReducer,
/* <CUSTOM_CALL_HEADER> */
mockCallScreenInformationHeaderReducer,
/* </CUSTOM_CALL_HEADER> */
buttonOptionsReducer,
)
val action = NavigationAction.CallLaunched()
@ -208,11 +204,9 @@ internal class AppReduxStateReducerUnitTest {
Mockito.`when`(mockCaptionsReducer.reduce(state.captionsState, action))
.thenReturn(state.captionsState)
/* <CUSTOM_CALL_HEADER> */
Mockito.`when`(mockCallScreenInformationHeaderReducer.reduce(state.callScreenInfoHeaderState, action)).thenReturn(
state.callScreenInfoHeaderState
)
/* </CUSTOM_CALL_HEADER> */
Mockito.`when`(buttonOptionsReducer.reduce(state.buttonState, action)).thenReturn(
state.buttonState

Просмотреть файл

@ -1,7 +1,5 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* <CUSTOM_CALL_HEADER> */
package com.azure.android.communication.ui.calling.redux.reducer
import com.azure.android.communication.ui.calling.redux.action.CallScreenInfoHeaderAction
@ -43,5 +41,3 @@ internal class CallScreenInfoHeaderReducerUnitTest {
Assert.assertEquals(subtitle, updatedState.subtitle)
}
}
/* </CUSTOM_CALL_HEADER> */

Просмотреть файл

@ -62,9 +62,7 @@ class CallCompositeManager(private val context: Context) {
val callCompositeCallStateStateFlow = MutableStateFlow("")
private var callComposite: CallComposite? = null
private var incomingCallId: String? = null
/* <CUSTOM_CALL_HEADER> */
private var callScreenHeaderOptions: CallCompositeCallScreenHeaderViewData? = null
/* </CUSTOM_CALL_HEADER> */
private var remoteParticipantsCount = 0
fun launch(
@ -310,14 +308,12 @@ class CallCompositeManager(private val context: Context) {
}
callComposite.addOnDismissedEventHandler(onDismissedEventHandler)
/* <CUSTOM_CALL_HEADER> */
callComposite.addOnRemoteParticipantLeftEventHandler { event ->
toast(context, "Remote participant removed: ${event.identifiers.count()}")
event.identifiers.forEach {
Log.d(CallLauncherActivity.TAG, "Remote participant removed: ${it.rawId}")
}
}
/* </CUSTOM_CALL_HEADER> */
callComposite.addOnPictureInPictureChangedEventHandler {
toast(context, "isInPictureInPicture: " + it.isInPictureInPicture)
@ -329,7 +325,6 @@ class CallCompositeManager(private val context: Context) {
Log.d(CallLauncherActivity.TAG, "Remote participant joined: ${it.rawId}")
}
remoteParticipantsCount += event.identifiers.count()
/* <CUSTOM_CALL_HEADER> */
val titleUpdateCount = SettingsFeatures.getCallScreenInformationTitleUpdateParticipantCount()
if (titleUpdateCount != 0 && titleUpdateCount <= remoteParticipantsCount) {
callScreenHeaderOptions?.let {
@ -342,7 +337,6 @@ class CallCompositeManager(private val context: Context) {
it.subtitle = "Custom Call Screen Header: $remoteParticipantsCount participants"
}
}
/* </CUSTOM_CALL_HEADER> */
}
callComposite.addOnAudioSelectionChangedEventHandler { event ->
@ -715,7 +709,6 @@ class CallCompositeManager(private val context: Context) {
)
}
}
/* <CUSTOM_CALL_HEADER> */
if (!SettingsFeatures.getCallScreenInformationTitle().isNullOrEmpty() ||
!SettingsFeatures.getCallScreenInformationSubtitle().isNullOrEmpty() ||
SettingsFeatures.getCallScreenInformationTitleUpdateParticipantCount() != 0 ||
@ -723,8 +716,8 @@ class CallCompositeManager(private val context: Context) {
) {
callScreenOptions = callScreenOptions ?: CallCompositeCallScreenOptions()
callScreenHeaderOptions =
CallCompositeCallScreenHeaderViewData()
callScreenHeaderOptions = callScreenHeaderOptions
?: CallCompositeCallScreenHeaderViewData()
SettingsFeatures.getCallScreenInformationTitle()?.let {
if (it.isNotEmpty()) {
callScreenHeaderOptions?.title = it
@ -735,9 +728,33 @@ class CallCompositeManager(private val context: Context) {
callScreenHeaderOptions?.subtitle = it
}
}
callScreenOptions.setHeaderViewData(callScreenHeaderOptions)
}
/* </CUSTOM_CALL_HEADER> */
/* <CALL_SCREEN_HEADER_CUSTOM_BUTTONS:0>
if (SettingsFeatures.getAddCustomButtons() == true) {
val headerButton1 =
CallCompositeCustomButtonViewData(
UUID.randomUUID().toString(),
R.drawable.ic_fluent_chat_24_regular,
"Header Button 1",
fun(it: CallCompositeCustomButtonClickEvent) {
toast(it.context, "Header Button 1 clicked")
}
)
val headerButton2 =
CallCompositeCustomButtonViewData(
UUID.randomUUID().toString(),
R.drawable.ic_fluent_arrow_next_24_regular,
"Header Button 2",
fun(it: CallCompositeCustomButtonClickEvent) {
toast(it.context, "Header Button 2 clicked")
}
)
callScreenHeaderOptions = callScreenHeaderOptions
?: CallCompositeCallScreenHeaderViewData()
callScreenHeaderOptions?.customButtons = listOf(headerButton1, headerButton2)
}
</CALL_SCREEN_HEADER_CUSTOM_BUTTONS> */
callScreenOptions?.setHeaderViewData(callScreenHeaderOptions)
return callScreenOptions
}

Просмотреть файл

@ -63,12 +63,10 @@ class SettingsActivity : AppCompatActivity() {
private lateinit var setupScreenOptionsCameraEnabledCheckbox: CheckBox
private lateinit var setupScreenOptionsMicEnabledCheckbox: CheckBox
private lateinit var defaultSpokenLanguageEditText: TextView
/* <CUSTOM_CALL_HEADER> */
private lateinit var updateTitleRemotePartiicpantCountEditBox: TextView
private lateinit var updateSubtitleRemotePartiicpantCountEditBox: TextView
private lateinit var callInformationTitleEditText: TextView
private lateinit var callInformationSubtitleEditText: TextView
/* </CUSTOM_CALL_HEADER> */
private lateinit var addCustomButtonsCheckbox: CheckBox
private val sharedPreference by lazy {
@ -168,7 +166,6 @@ class SettingsActivity : AppCompatActivity() {
updateCustomButtonsCheckbox()
defaultSpokenLanguageEditText.text = sharedPreference.getString(DEFAULT_SPOKEN_LANGUAGE_KEY, DEFAULT_SPOKEN_LANGUAGE)
/* <CUSTOM_CALL_HEADER> */
sharedPreference.getInt(CALL_INFORMATION_TITLE_UPDATE_PARTICIPANT_COUNT_KEY, CALL_INFORMATION_TITLE_UPDATE_PARTICIPANT_COUNT_VALUE).toString()
.let {
if (it.isNotEmpty() && it != "0") {
@ -182,7 +179,6 @@ class SettingsActivity : AppCompatActivity() {
}
callInformationTitleEditText.text = sharedPreference.getString(CALL_INFORMATION_TITLE_KEY, CALL_INFORMATION_DEFAULT_TITLE)
callInformationSubtitleEditText.text = sharedPreference.getString(CALL_INFORMATION_SUBTITLE_KEY, CALL_INFORMATION_SUBTITLE_DEFAULT)
/* </CUSTOM_CALL_HEADER> */
autoCompleteTextView.setOnItemClickListener { _, _, position, _ ->
val selectedItem: String = supportedLanguages[position]
setLanguageValueInSharedPref(selectedItem)
@ -199,11 +195,6 @@ class SettingsActivity : AppCompatActivity() {
saveSetupScreenOrientationInSharedPref(selectedItem)
}
setupScreenOrientationAutoCompleteTextView.setOnItemClickListener { _, _, position, _ ->
val selectedItem: String = telecomManagerIntegrationOptions[position]
saveTelecomManagerIntegrationOptionInSharedPref(selectedItem)
}
telecomManagerAutoCompleteTextView.setOnItemClickListener { _, _, position, _ ->
val selectedItem: String = telecomManagerIntegrationOptions[position]
saveTelecomManagerIntegrationOptionInSharedPref(selectedItem)
@ -379,12 +370,10 @@ class SettingsActivity : AppCompatActivity() {
setupScreenOptionsCameraEnabledCheckbox = findViewById(R.id.setup_screen_camera_check_box)
setupScreenOptionsMicEnabledCheckbox = findViewById(R.id.setup_screen_mic_check_box)
defaultSpokenLanguageEditText = findViewById(R.id.default_spoken_language_edit_text)
/* <CUSTOM_CALL_HEADER> */
updateTitleRemotePartiicpantCountEditBox = findViewById(R.id.call_information_title_update_remote_participant_count)
updateSubtitleRemotePartiicpantCountEditBox = findViewById(R.id.call_information_subtitle_update_remote_participant_count)
callInformationTitleEditText = findViewById(R.id.call_information_title_edit_text)
callInformationSubtitleEditText = findViewById(R.id.call_information_subtitle_edit_text)
/* </CUSTOM_CALL_HEADER> */
addCustomButtonsCheckbox = findViewById(R.id.add_custom_buttons_option_checkbox)
@ -404,7 +393,6 @@ class SettingsActivity : AppCompatActivity() {
defaultSpokenLanguageEditText.text.toString()
).apply()
}
/* <CUSTOM_CALL_HEADER> */
updateTitleRemotePartiicpantCountEditBox.addTextChangedListener {
if (updateTitleRemotePartiicpantCountEditBox.text.isNullOrEmpty()) {
sharedPreference.edit().putInt(
@ -446,7 +434,6 @@ class SettingsActivity : AppCompatActivity() {
callInformationSubtitleEditText.text.toString()
).apply()
}
/* </CUSTOM_CALL_HEADER> */
}
private fun updateRTLCheckbox() {
@ -748,7 +735,6 @@ const val DEFAULT_HIDE_CAPTIONS_UI = false
const val DEFAULT_SPOKEN_LANGUAGE_KEY = "DEFAULT_SPOKEN_LANGUAGE"
const val DEFAULT_SPOKEN_LANGUAGE = ""
/* <CUSTOM_CALL_HEADER> */
const val CALL_INFORMATION_TITLE_UPDATE_PARTICIPANT_COUNT_KEY = "TITLE_UPDATE_PARTICIPANT_COUNT"
const val CALL_INFORMATION_SUBTITLE_UPDATE_PARTICIPANT_COUNT_KEY = "SUBTITLE_UPDATE_PARTICIPANT_COUNT"
const val CALL_INFORMATION_SUBTITLE_UPDATE_PARTICIPANT_COUNT_VALUE = 0
@ -759,6 +745,5 @@ const val CALL_INFORMATION_DEFAULT_TITLE = ""
const val CALL_INFORMATION_SUBTITLE_KEY = "CALL_INFORMATION_SUBTITLE"
const val CALL_INFORMATION_SUBTITLE_DEFAULT = ""
/* </CUSTOM_CALL_HEADER> */
const val ADD_CUSTOM_BUTTONS_KEY = "ADD_CUSTOM_BUTTONS"
const val DEFAULT_ADD_CUSTOM_BUTTONS = false

Просмотреть файл

@ -12,7 +12,6 @@ import com.azure.android.communication.ui.callingcompositedemoapp.ADD_CUSTOM_BUT
import com.azure.android.communication.ui.callingcompositedemoapp.AUDIO_ONLY_MODE_ON
import com.azure.android.communication.ui.callingcompositedemoapp.AUTO_START_CAPTIONS
import com.azure.android.communication.ui.callingcompositedemoapp.AVATAR_IMAGE
/* <CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.callingcompositedemoapp.CALL_INFORMATION_DEFAULT_TITLE
import com.azure.android.communication.ui.callingcompositedemoapp.CALL_INFORMATION_SUBTITLE_DEFAULT
import com.azure.android.communication.ui.callingcompositedemoapp.CALL_INFORMATION_SUBTITLE_KEY
@ -21,7 +20,6 @@ import com.azure.android.communication.ui.callingcompositedemoapp.CALL_INFORMATI
import com.azure.android.communication.ui.callingcompositedemoapp.CALL_INFORMATION_TITLE_KEY
import com.azure.android.communication.ui.callingcompositedemoapp.CALL_INFORMATION_TITLE_UPDATE_PARTICIPANT_COUNT_KEY
import com.azure.android.communication.ui.callingcompositedemoapp.CALL_INFORMATION_TITLE_UPDATE_PARTICIPANT_COUNT_VALUE
/* </CUSTOM_CALL_HEADER> */
import com.azure.android.communication.ui.callingcompositedemoapp.CALL_SCREEN_ORIENTATION_SHARED_PREF_KEY
import com.azure.android.communication.ui.callingcompositedemoapp.CALL_SUBTITLE
import com.azure.android.communication.ui.callingcompositedemoapp.CALL_TITLE
@ -89,7 +87,6 @@ class SettingsFeatures {
DEFAULT_SPOKEN_LANGUAGE,
)
}
/* <CUSTOM_CALL_HEADER> */
fun getCallScreenInformationTitleUpdateParticipantCount(): Int {
return sharedPrefs.getInt(
CALL_INFORMATION_TITLE_UPDATE_PARTICIPANT_COUNT_KEY,
@ -117,7 +114,6 @@ class SettingsFeatures {
CALL_INFORMATION_DEFAULT_TITLE,
)
}
/* </CUSTOM_CALL_HEADER> */
fun getLayoutDirection(): Int? {
val isRTLKey =
LANGUAGE_ISRTL_VALUE_SHARED_PREF_KEY +

Просмотреть файл

@ -463,7 +463,6 @@
android:text="@string/display_leave_call_confirmation"
tools:ignore="UsingOnClickInXml"
/>
<!-- <CUSTOM_CALL_HEADER> -->
<EditText
android:id="@+id/call_information_title_edit_text"
android:layout_width="match_parent"
@ -497,7 +496,6 @@
android:inputType="number|text"
android:hint="@string/update_subtitle_remote_participant_count"
/>
<!-- </CUSTOM_CALL_HEADER> -->
<TextView
android:id="@+id/telecom_manager_options"
android:layout_width="match_parent"

Просмотреть файл

@ -16,6 +16,7 @@
<item name="azure_communication_ui_calling_primary_color_tint10">#882BD8</item>
<item name="azure_communication_ui_calling_primary_color_tint20">#E0C7F4</item>
<item name="azure_communication_ui_calling_primary_color_tint30">#ECDEF9</item>
<item name="azure_communication_ui_calling_foreground_on_primary_color">#00FF00</item>
</style>
</resources>

Просмотреть файл

@ -0,0 +1,13 @@
<!--
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/white"
android:pathData="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10c-1.618 0-3.182-0.385-4.587-1.112l-3.826 1.067c-0.665 0.186-1.354-0.202-1.54-0.867-0.062-0.22-0.062-0.453 0-0.673l1.068-3.823C2.386 15.186 2 13.62 2 12 2 6.477 6.477 2 12 2zm0 1.5c-4.694 0-8.5 3.806-8.5 8.5 0 1.47 0.373 2.883 1.073 4.137l0.15 0.27-1.112 3.984 3.986-1.112 0.27 0.15C9.12 20.13 10.532 20.5 12 20.5c4.694 0 8.5-3.806 8.5-8.5S16.694 3.5 12 3.5zM8.75 13h4.498c0.415 0 0.75 0.336 0.75 0.75 0 0.38-0.282 0.694-0.648 0.743L13.248 14.5H8.75C8.336 14.5 8 14.164 8 13.75c0-0.38 0.282-0.694 0.648-0.743L8.75 13h4.498H8.75zm0-3.5h6.505c0.414 0 0.75 0.336 0.75 0.75 0 0.38-0.283 0.694-0.649 0.743L15.255 11H8.75C8.336 11 8 10.664 8 10.25c0-0.38 0.282-0.694 0.648-0.743L8.75 9.5h6.505H8.75z" />
</vector>

Просмотреть файл

@ -86,12 +86,10 @@
<string name="auto_start_captions_text">Auto start captions.</string>
<string name="hide_captions_text">Hide captions start/stop UI.</string>
<string name="default_spoken_language">Default spoken language.</string>
<!-- <CUSTOM_CALL_HEADER> -->
<string name="call_information_subtitle">Call information subtitle</string>
<string name="call_information_subtitle">Call information subtitle</string>
<string name="update_title_remote_participant_count">Set participant count in title if greater than</string>
<string name="update_subtitle_remote_participant_count">Set participant count in subtitle if greater than</string>
<string name="call_information_title">Call information title</string>
<!-- </CUSTOM_CALL_HEADER> -->
<string name="call_custom_buttons_text">Custom Buttons</string>
<string name="call_custom_buttons">Add Custom Buttons</string>
</resources>

Просмотреть файл

@ -1,4 +1,14 @@
# Azure Communication UI Calling Release History
## 1.12.0 (2024-10-31)
### Features
- Color theming support for button font color.
## 1.12.0-beta.1 (2024-10-10)
### Features
- Call screen header custom button
- Color theming support
## 1.11.0 (2024-09-25)