INTEGRITY Документация

Add Custom Controlbar

В этом руководстве мы покажем, как добавить собственную controlbar для интерфейса встречи RealtimeKit.

RealtimeKit UI Kit предоставляет RtkControlbar компонент для стандартной панели управления.

Если вам нужны дополнительные элементы управления, замените RtkControlbar с отдельными компонентами UI Kit и пользовательскими элементами.

Импортируйте необходимые компоненты и React-хук:

import { useRef } from "react";
import {
	RtkFullscreenToggle,
	RtkSettingsToggle,
	RtkScreenShareToggle,
	RtkMicToggle,
	RtkCameraToggle,
	RtkStageToggle,
	RtkLeaveButton,
	RtkMoreToggle,
	RtkPipToggle,
	RtkMuteAllButton,
	RtkBreakoutRoomsToggle,
	RtkRecordingToggle,
	RtkChatToggle,
	RtkPollsToggle,
	RtkParticipantsToggle,
	RtkPluginsToggle,
} from "@cloudflare/realtimekit-ui";

В вашем RtkUIProvider от Создание собственного интерфейса, замените:

<RtkControlbar />

с:

<div
	style={{
		display: "flex",
		width: "100%",
		padding: "8px 12px",
		color: "white",
		justifyContent: "space-between",
	}}
>
	<div
		id="controlbar-left"
		style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
	>
		<RtkFullscreenToggle targetElement={fullScreenRef.current} />
		<RtkSettingsToggle />
		<RtkScreenShareToggle />
	</div>
	<div
		id="controlbar-center"
		style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
	>
		<RtkMicToggle />
		<RtkCameraToggle />
		<RtkStageToggle />
		<RtkLeaveButton />
		<RtkMoreToggle>
			<div slot="more-elements">
				<RtkPipToggle variant="horizontal" />
				<RtkMuteAllButton variant="horizontal" />
				<RtkBreakoutRoomsToggle variant="horizontal" />
				<RtkRecordingToggle variant="horizontal" />
			</div>
		</RtkMoreToggle>
	</div>
	<div
		id="controlbar-right"
		style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
	>
		<RtkChatToggle />
		<RtkPollsToggle />
		<RtkParticipantsToggle />
		<RtkPluginsToggle />
	</div>
</div>

Определите ref для цели полноэкранного режима и прикрепите его к своему контейнеру:

const fullScreenRef = useRef<HTMLDivElement>(null);

// In your RtkUIProvider, add the ref to the container
<RtkUIProvider
	ref={fullScreenRef}
	meeting={meeting}
	showSetupScreen={false}
	style={{
		display: "flex",
		flexDirection: "column",
		height: "100vh",
		margin: 0,
	}}
>
	{/* Your controlbar and other components */}
</RtkUIProvider>

// Pass the ref's current element to RtkFullscreenToggle
<RtkFullscreenToggle targetElement={fullScreenRef.current} />

Полный пример создания собственного интерфейса с пользовательским controlbar можно найти здесь с пользовательским компонентом controlbar здесь.

RealtimeKit UI Kit предоставляет rtk-controlbar компонент для стандартной панели управления.

Если вам нужны дополнительные элементы управления, замените rtk-controlbar с отдельными компонентами UI Kit и пользовательскими элементами. В renderJoinedScreen функцию из Создание собственного интерфейса, замените:

<rtk-controlbar
	style="display: flex; justify-content: space-between;"
></rtk-controlbar>

с:

<div
	style="display: flex; width: 100%; padding: 8px 12px; color: white; justify-content: space-between;"
>
	<div
		id="controlbar-left"
		style="display: flex; align-items: center; justify-content: center;"
	>
		<rtk-fullscreen-toggle id="fullscreen-toggle"></rtk-fullscreen-toggle>
		<rtk-settings-toggle></rtk-settings-toggle>
		<rtk-screen-share-toggle></rtk-screen-share-toggle>
	</div>
	<div
		id="controlbar-center"
		style="display: flex; align-items: center; justify-content: center;"
	>
		<rtk-mic-toggle></rtk-mic-toggle>
		<rtk-camera-toggle></rtk-camera-toggle>
		<rtk-stage-toggle></rtk-stage-toggle>
		<rtk-leave-button></rtk-leave-button>
		<rtk-more-toggle>
			<div slot="more-elements">
				<rtk-pip-toggle variant="horizontal"></rtk-pip-toggle>
				<rtk-mute-all-button variant="horizontal"></rtk-mute-all-button>
				<rtk-breakout-rooms-toggle
					variant="horizontal"
				></rtk-breakout-rooms-toggle>
				<rtk-recording-toggle variant="horizontal"></rtk-recording-toggle>
			</div>
		</rtk-more-toggle>
	</div>
	<div
		id="controlbar-right"
		style="display: flex; align-items: center; justify-content: center;"
	>
		<rtk-chat-toggle></rtk-chat-toggle>
		<rtk-polls-toggle></rtk-polls-toggle>
		<rtk-participants-toggle></rtk-participants-toggle>
		<rtk-plugins-toggle></rtk-plugins-toggle>
	</div>
</div>

Зарегистрируйте цель полноэкранного режима после рендеринга:

const fullscreenToggle = document.querySelector("#fullscreen-toggle");
if (fullscreenToggle) {
	const targetElement = document.querySelector("rtk-ui-provider");
	if (targetElement) {
		fullscreenToggle.targetElement = targetElement;
	}
}

Полный пример создания собственного интерфейса с пользовательским controlbar можно найти здесь с пользовательским компонентом controlbar здесь.

RealtimeKit UI Kit предоставляет rtk-controlbar компонент для стандартной панели управления.

Если вам нужны дополнительные элементы управления, замените rtk-controlbar с отдельными компонентами UI Kit и пользовательскими элементами. Создайте собственный компонент controlbar, который напрямую использует Angular-компоненты RealtimeKit.

Создание пользовательского компонента Controlbar

custom-controlbar.component.ts
import { Component, AfterViewInit, ElementRef, ViewChild } from "@angular/core";

@Component({
	selector: "app-custom-controlbar",
	template: `
		<div class="custom-controlbar">
			<div class="controlbar-left">
				<rtk-fullscreen-toggle #fullscreenToggle></rtk-fullscreen-toggle>
				<rtk-settings-toggle></rtk-settings-toggle>
				<rtk-screen-share-toggle></rtk-screen-share-toggle>
			</div>

			<div class="controlbar-center">
				<rtk-mic-toggle></rtk-mic-toggle>
				<rtk-camera-toggle></rtk-camera-toggle>
				<rtk-stage-toggle></rtk-stage-toggle>
				<rtk-leave-button></rtk-leave-button>
				<rtk-more-toggle>
					<div slot="more-elements">
						<rtk-pip-toggle variant="horizontal"></rtk-pip-toggle>
						<rtk-mute-all-button variant="horizontal"></rtk-mute-all-button>
						<rtk-breakout-rooms-toggle
							variant="horizontal"
						></rtk-breakout-rooms-toggle>
						<rtk-recording-toggle variant="horizontal"></rtk-recording-toggle>
					</div>
				</rtk-more-toggle>
			</div>

			<div class="controlbar-right">
				<rtk-chat-toggle></rtk-chat-toggle>
				<rtk-polls-toggle></rtk-polls-toggle>
				<rtk-participants-toggle></rtk-participants-toggle>
				<rtk-plugins-toggle></rtk-plugins-toggle>
			</div>
		</div>
	`,
	styles: [
		`
			.custom-controlbar {
				display: flex;
				width: 100%;
				padding: 8px 12px;
				color: white;
				justify-content: space-between;
				background-color: rgba(0, 0, 0, 0.8);
				border-radius: 8px;
			}

			.controlbar-left,
			.controlbar-center,
			.controlbar-right {
				display: flex;
				align-items: center;
				justify-content: center;
				gap: 8px;
			}

			.controlbar-center {
				flex: 1;
				justify-content: center;
			}
		`,
	],
})
export class CustomControlbarComponent implements AfterViewInit {
	@ViewChild("fullscreenToggle", { static: true })
	fullscreenToggle!: ElementRef;

	ngAfterViewInit() {
		// Register the fullscreen target after rendering
		this.setupFullscreenToggle();
	}

	private setupFullscreenToggle() {
		const fullscreenElement = this.fullscreenToggle?.nativeElement;
		if (fullscreenElement) {
			const targetElement = document.querySelector("rtk-ui-provider");
			if (targetElement) {
				fullscreenElement.targetElement = targetElement;
			}
		}
	}
}

Использование в компоненте встречи

В шаблоне основного компонента встречи замените:

<rtk-controlbar
	style="display: flex; justify-content: space-between;"
></rtk-controlbar>

с:

<app-custom-controlbar></app-custom-controlbar>

Полный пример компонента встречи

meeting.component.ts
import {
	Component,
	ElementRef,
	OnInit,
	OnDestroy,
	ViewChild,
} from "@angular/core";

@Component({
	selector: "app-meeting",
	template: `
		<rtk-meeting #meetingComponent id="meeting-component">
			<!-- Other meeting UI components -->
			<rtk-grid></rtk-grid>
			<rtk-sidebar></rtk-sidebar>

			<!-- Custom controlbar replaces rtk-controlbar -->
			<app-custom-controlbar></app-custom-controlbar>
		</rtk-meeting>
	`,
})
export class MeetingComponent implements OnInit, OnDestroy {
	@ViewChild("meetingComponent", { static: true }) meetingElement!: ElementRef;

	meeting: any;
	private authToken = "<participant_auth_token>";

	async ngOnInit() {
		const RealtimeKitClient = await import(
			"https://cdn.jsdelivr.net/npm/@cloudflare/realtimekit@latest/dist/index.es.js"
		);

		this.meeting = await RealtimeKitClient.default.init({
			authToken: this.authToken,
		});

		const meetingComponent = this.meetingElement.nativeElement;
		meetingComponent.showSetupScreen = true;
		meetingComponent.meeting = this.meeting;
	}

	ngOnDestroy() {
		// Cleanup logic
	}
}

Конфигурация модуля

Не забудьте объявить свой пользовательский компонент controlbar в модуле Angular:

app.module.ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";

import { AppComponent } from "./app.component";
import { MeetingComponent } from "./meeting.component";
import { CustomControlbarComponent } from "./custom-controlbar.component";

@NgModule({
	declarations: [AppComponent, MeetingComponent, CustomControlbarComponent],
	imports: [BrowserModule],
	providers: [],
	bootstrap: [AppComponent],
	schemas: [CUSTOM_ELEMENTS_SCHEMA], // Required for RTK web components
})
export class AppModule {}

Расширенная настройка

Вы можете дополнительно настроить controlbar, добавив собственные кнопки или изменив макет:

enhanced-controlbar.component.ts
import { Component, AfterViewInit, ElementRef, ViewChild } from "@angular/core";

@Component({
	selector: "app-enhanced-controlbar",
	template: `
		<div class="custom-controlbar">
			<div class="controlbar-left">
				<rtk-fullscreen-toggle #fullscreenToggle></rtk-fullscreen-toggle>
				<rtk-settings-toggle></rtk-settings-toggle>
				<button class="custom-button" (click)="onCustomAction()">
					Custom Action
				</button>
			</div>

			<div class="controlbar-center">
				<rtk-mic-toggle></rtk-mic-toggle>
				<rtk-camera-toggle></rtk-camera-toggle>
				<rtk-stage-toggle></rtk-stage-toggle>
				<rtk-leave-button></rtk-leave-button>
			</div>

			<div class="controlbar-right">
				<rtk-chat-toggle></rtk-chat-toggle>
				<rtk-participants-toggle></rtk-participants-toggle>
			</div>
		</div>
	`,
	styles: [
		`
			.custom-controlbar {
				display: flex;
				width: 100%;
				padding: 8px 12px;
				color: white;
				justify-content: space-between;
				background-color: rgba(0, 0, 0, 0.8);
				border-radius: 8px;
			}

			.controlbar-left,
			.controlbar-center,
			.controlbar-right {
				display: flex;
				align-items: center;
				justify-content: center;
				gap: 8px;
			}

			.custom-button {
				background: #0051c3;
				border: none;
				color: white;
				padding: 8px 12px;
				border-radius: 4px;
				cursor: pointer;
				font-size: 12px;
			}

			.custom-button:hover {
				background: #003d99;
			}
		`,
	],
})
export class EnhancedControlbarComponent implements AfterViewInit {
	@ViewChild("fullscreenToggle", { static: true })
	fullscreenToggle!: ElementRef;

	ngAfterViewInit() {
		this.setupFullscreenToggle();
	}

	private setupFullscreenToggle() {
		const fullscreenElement = this.fullscreenToggle?.nativeElement;
		if (fullscreenElement) {
			const targetElement = document.querySelector("rtk-ui-provider");
			if (targetElement) {
				fullscreenElement.targetElement = targetElement;
			}
		}
	}

	onCustomAction() {
		console.log("Custom action triggered");
		// Add your custom logic here
	}
}

Такой подход даёт вам полный контроль над раскладкой controlbar, сохраняя компонентную архитектуру Angular и используя встроенные возможности RealtimeKit.

iOS UI Kit предоставляет RtkMeetingControlBar в качестве стандартного controlbar для групповых встреч. Чтобы создать собственный controlbar, скомпонуйте отдельные компоненты кнопок внутри RtkTabBar.

Доступные компоненты кнопок controlbar

Компонент Описание
RtkAudioButtonControlBar Переключатель микрофона с автоматическим управлением состоянием
RtkVideoButtonControlBar Переключатель камеры с автоматическим управлением состоянием
RtkEndMeetingControlBarButton Кнопка выхода/завершения встречи с диалоговым окном подтверждения
RtkMoreButtonControlBar Кнопка меню «Ещё» с нижней панелью
RtkSwitchCameraButtonControlBar Переключение между фронтальной и основной камерой
RtkStageActionButtonControlBar Присоединение к сцене и уход со сцены на вебинарах и прямых трансляциях
RtkControlBarButton Базовый класс кнопки для пользовательских кнопок
RtkControlBarSpacerButton Невидимый разделитель для макета

Создание пользовательского controlbar с помощью RtkTabBar

Создайте RtkTabBar и добавьте отдельные компоненты кнопок:

import RealtimeKitUI
import RealtimeKit

func buildCustomControlBar(
    meeting: RealtimeKitClient,
    viewController: UIViewController
) -> RtkTabBar {
    let tabBar = RtkTabBar(delegate: nil)

    let micButton = RtkAudioButtonControlBar(meeting: meeting)
    let videoButton = RtkVideoButtonControlBar(rtkClient: meeting)
    let switchCameraButton = RtkSwitchCameraButtonControlBar(meeting: meeting)
    let endCallButton = RtkEndMeetingControlBarButton(
        meeting: meeting,
        alertViewController: viewController
    )

    tabBar.setButtons([micButton, videoButton, switchCameraButton, endCallButton])
    return tabBar
}

Добавьте пользовательский controlbar в ваш view controller

override func viewDidLoad() {
    super.viewDidLoad()

    let controlBar = buildCustomControlBar(
        meeting: meeting,
        viewController: self
    )
    controlBar.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(controlBar)

    NSLayoutConstraint.activate([
        controlBar.bottomAnchor.constraint(
            equalTo: view.safeAreaLayoutGuide.bottomAnchor
        ),
        controlBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        controlBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        controlBar.heightAnchor.constraint(equalToConstant: 80),
    ])
}

Используйте паттерн DataSource для замены кнопок

Реализуйте RtkMeetingControlBarDataSource чтобы заменить отдельные кнопки, сохранив стандартную раскладку controlbar:

class CustomControlBarDataSource: RtkMeetingControlBarDataSource {
    func getMicControlBarButton(
        for meeting: RealtimeKitClient
    ) -> RtkControlBarButton? {
        // Return a custom mic button, or nil to use the default
        let button = RtkAudioButtonControlBar(meeting: meeting)
        return button
    }

    func getVideoControlBarButton(
        for meeting: RealtimeKitClient
    ) -> RtkControlBarButton? {
        // Return a custom video button, or nil to use the default
        let button = RtkVideoButtonControlBar(rtkClient: meeting)
        return button
    }
}

// Assign the data source
let controlBar = RtkMeetingControlBar(
    meeting: meeting,
    delegate: nil,
    presentingViewController: self
)
controlBar.dataSource = CustomControlBarDataSource()

Добавьте пользовательские кнопки

Создание пользовательской кнопки с использованием RtkControlBarButton:

let customButton = RtkControlBarButton(
    image: RtkImage(image: UIImage(systemName: "hand.raised.fill")),
    title: "Raise Hand"
)
customButton.addTarget(self, action: #selector(onRaiseHand), for: .touchUpInside)

// Add it alongside other buttons
tabBar.setButtons([micButton, videoButton, customButton, endCallButton])

Android UI Kit предоставляет RtkMeetingControlBarView в качестве стандартного controlbar. Чтобы создать собственный controlbar, используйте отдельные компоненты кнопок в XML-разметке и активируйте их с помощью объекта meeting.

Доступные компоненты кнопок controlbar

Компонент Активируйте с помощью Описание
RtkMicToggleButton RealtimeKitClient Переключатель микрофона с управлением состоянием
RtkCameraToggleButton RealtimeKitClient Переключатель камеры с управлением состоянием
RtkLeaveButton RealtimeKitClient Кнопка выхода/завершения встречи с диалоговым окном подтверждения
RtkMoreToggleButton RealtimeKitClient Кнопка меню «Ещё»
RtkControlBarButton , Базовый класс кнопки для пользовательских кнопок

Определение разметки пользовательского controlbar в XML

layout_custom_controlbar.xml
<?xml version="1.0" encoding="utf-8"?>
<com.cloudflare.realtimekit.ui.view.controlbars.RtkControlBarView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/customControlBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:padding="8dp">

    <com.cloudflare.realtimekit.ui.view.controlbarbuttons.RtkMicToggleButton
        android:id="@+id/micToggle"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_margin="4dp" />

    <com.cloudflare.realtimekit.ui.view.controlbarbuttons.RtkCameraToggleButton
        android:id="@+id/cameraToggle"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_margin="4dp" />

    <com.cloudflare.realtimekit.ui.view.controlbarbuttons.RtkMoreToggleButton
        android:id="@+id/moreToggle"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_margin="4dp" />

    <com.cloudflare.realtimekit.ui.view.controlbarbuttons.RtkLeaveButton
        android:id="@+id/leaveButton"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_margin="4dp" />

</com.cloudflare.realtimekit.ui.view.controlbars.RtkControlBarView>

Активируйте кнопки controlbar в своей Activity

CustomMeetingActivity.kt
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.cloudflare.realtimekit.RealtimeKitClient
import com.cloudflare.realtimekit.ui.view.controlbarbuttons.RtkMicToggleButton
import com.cloudflare.realtimekit.ui.view.controlbarbuttons.RtkCameraToggleButton
import com.cloudflare.realtimekit.ui.view.controlbarbuttons.RtkMoreToggleButton
import com.cloudflare.realtimekit.ui.view.controlbarbuttons.RtkLeaveButton

class CustomMeetingActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_custom_meeting)

        // Your meeting initialization code...
    }

    fun activateControlBar(meeting: RealtimeKitClient) {
        findViewById<RtkMicToggleButton>(R.id.micToggle).activate(meeting)
        findViewById<RtkCameraToggleButton>(R.id.cameraToggle).activate(meeting)
        findViewById<RtkMoreToggleButton>(R.id.moreToggle).activate(meeting)
        findViewById<RtkLeaveButton>(R.id.leaveButton).activate(meeting)
    }
}

Добавьте пользовательские кнопки с помощью RtkControlBarButton

Создание пользовательской кнопки в XML:

<com.cloudflare.realtimekit.ui.view.controlbarbuttons.RtkControlBarButton
    android:id="@+id/raiseHandButton"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:layout_margin="4dp"
    android:text="Raise Hand"
    app:rtk_cbb_icon="@drawable/ic_raise_hand"
    app:rtk_cbb_variant="BUTTON"
    app:rtk_cbb_showText="true" />

Обработка нажатия в Kotlin:

val raiseHandButton = findViewById<RtkControlBarButton>(R.id.raiseHandButton)
raiseHandButton.setOnClickListener {
    // Custom raise hand logic
}

React Native UI Kit предоставляет отдельные компоненты-переключатели, из которых можно собрать собственный controlbar.

Доступные компоненты controlbar

Компонент Обязательный проп Описание
RtkMicToggle meeting Переключатель микрофона с обработкой разрешений
RtkCameraToggle meeting Переключатель камеры с обработкой разрешений
RtkLeaveButton , Кнопка выхода/завершения встречи с диалоговым окном подтверждения
RtkMoreToggle meeting Переключатель меню «Ещё» со значком уведомления
RtkScreenShareToggle meeting Переключатель демонстрации экрана
RtkControlbarButton , Базовая кнопка для пользовательских действий

Создание пользовательского controlbar

Замените RtkControlbar с отдельными компонентами в View:

import React from "react";
import { View, StyleSheet } from "react-native";
import {
	RtkMicToggle,
	RtkCameraToggle,
	RtkLeaveButton,
	RtkMoreToggle,
	RtkScreenShareToggle,
} from "@cloudflare/realtimekit-react-native-ui";

function CustomControlbar({ meeting }) {
	return (
		<View style={styles.controlbar}>
			<RtkMicToggle meeting={meeting} variant="horizontal" />
			<RtkCameraToggle meeting={meeting} variant="horizontal" />
			<RtkScreenShareToggle meeting={meeting} variant="horizontal" />
			<RtkMoreToggle meeting={meeting} variant="horizontal" />
			<RtkLeaveButton />
		</View>
	);
}

const styles = StyleSheet.create({
	controlbar: {
		flexDirection: "row",
		justifyContent: "space-evenly",
		alignItems: "center",
		backgroundColor: "#1A1A1A",
		paddingVertical: 8,
		paddingHorizontal: 16,
	},
});

Используйте пользовательский controlbar на экране встречи

В вашем MeetingScreens компонент из Создание собственного интерфейса, замените:

<RtkControlbar meeting={meeting} />

с:

<CustomControlbar meeting={meeting} />

Добавьте пользовательские кнопки с помощью RtkControlbarButton

Используйте RtkControlbarButton чтобы создавать кнопки, соответствующие дизайну RealtimeKit:

import { RtkControlbarButton } from "@cloudflare/realtimekit-react-native-ui";

function CustomControlbar({ meeting }) {
	return (
		<View style={styles.controlbar}>
			<RtkMicToggle meeting={meeting} variant="horizontal" />
			<RtkCameraToggle meeting={meeting} variant="horizontal" />
			<RtkControlbarButton
				label="Raise Hand"
				icon={raiseHandSvg}
				onClick={() => {
					// Custom raise hand logic
				}}
				variant="horizontal"
			/>
			<RtkLeaveButton />
		</View>
	);
}