Integrasi Ionic dengan CometChat Calls SDK
Prasyarat
Sebelum memulai, pastikan Anda memiliki:
- Akun CometChat dengan aplikasi yang sudah dibuat
- ID Aplikasi, Region, dan Kunci API dari Dasbor CometChat
- Proyek Ionic (Angular, React, atau Vue)
- Node 16+ terinstal
- Ionic CLI terinstal (
npm install -g @ionic/cli)
Langkah 1: Instal SDK
Instal paket CometChat Calls SDK:
npm install @cometchat/calls-sdk-javascriptIonic Angular
Langkah 2: Buat Service
Buat service yang menangani inisialisasi SDK, autentikasi, dan operasi panggilan. Service menunggu platform Ionic siap sebelum inisialisasi:
// src/app/services/service
import { Injectable } from "@angular/core";
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
import { Platform } from "@ionic/angular";
import { BehaviorSubject } from "rxjs";
interface User {
uid: string;
name: string;
avatar?: string;
}
@Injectable({
providedIn: "root",
})
export class CometChatCallsService {
private initialized = false;
private _isReady$ = new BehaviorSubject<boolean>(false);
private _user$ = new BehaviorSubject<User | null>(null);
private _error$ = new BehaviorSubject<string | null>(null);
isReady$ = this._isReady$.asObservable();
user$ = this._user$.asObservable();
error$ = this._error$.asObservable();
// Ganti dengan kredensial CometChat Anda
private readonly APP_ID = "YOUR_APP_ID";
private readonly REGION = "YOUR_REGION";
private readonly API_KEY = "YOUR_API_KEY";
constructor(private platform: Platform) {}
async initAndLogin(uid: string): Promise<boolean> {
try {
// Tunggu platform Ionic siap
await platform();
if (thislized) {
return true;
}
// Langkah 1: Inisialisasi SDK
const initResult = await CometChatCalls({
appId: this_ID,
region: this,
});
if (!initResults) {
throw new Error("Inisialisasi SDK gagal");
}
// Langkah 2: Periksa apakah sudah login
let loggedInUser = CometChatCallsgedInUser();
// Langkah 3: Login jika belum
if (!loggedInUser) {
loggedInUser = await CometChatCalls(uid, this_KEY);
}
thislized = true;
this._user$.next(loggedInUser);
this._isReady$.next(true);
return true;
} catch (err: any) {
console("Pengaturan CometChat Calls gagal:", err);
this._error$.next(erre || "Pengaturan gagal");
return false;
}
}
getLoggedInUser(): User | null {
return this._user$.value;
}
async generateToken(sessionId: string) {
return CometChatCallsteToken(sessionId);
}
async joinSession(token: string, settings: any, container: HTMLElement) {
return CometChatCallsssion(token, settings, container);
}
leaveSession() {
CometChatCallsession();
}
muteAudio() {
CometChatCallsdio();
}
unMuteAudio() {
CometChatCallsAudio();
}
pauseVideo() {
CometChatCallsideo();
}
resumeVideo() {
CometChatCallsVideo();
}
addEventListener(event: string, callback: Function) {
return CometChatCallsntListener(event as any, callback as any);
}
}Langkah 3: Inisialisasi di App Component
Inisialisasi SDK dan login saat aplikasi dimulai:
// src/app/component
import { Component, OnInit } from "@angular/core";
import { CometChatCallsService } from "./services/cometchat-callse";
@Component({
selector: "app-root",
templateUrl: "component",
})
export class AppComponent implements OnInit {
constructor(private callsService: CometChatCallsService) {}
ngOnInit() {
// Di aplikasi nyata, ambil dari sistem autentikasi Anda
const currentUserId = "cometchat-uid-1";
callsServicedLogin(currentUserId);
}
}Langkah 4: Buat Halaman Panggilan
Buat komponen halaman panggilan yang menangani bergabung sesi, kontrol media, dan pembersihan:
// src/app/pages/call/page
import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { NavController } from "@ionic/angular";
import { CometChatCallsService } from "../../services/cometchat-callse";
import { Subscription } from "rxjs";
@Component({
selector: "app-call",
templateUrl: "./page",
styleUrls: ["./page"],
})
export class CallPage implements OnInit, OnDestroy {
@ViewChild("callContainer", { static: true }) callContainer!: ElementRef;
sessionId: string = "";
isReady = false;
isJoined = false;
isJoining = false;
isMuted = false;
isVideoOff = false;
error: string | null = null;
private unsubscribers: Function[] = [];
private subscriptions: Subscription[] = [];
constructor(
private route: ActivatedRoute,
private navCtrl: NavController,
private callsService: CometChatCallsService
) {}
ngOnInit() {
thisnId = paramMap("sessionId") || "";
// Berlangganan status siap
subscriptions(
callsServicey$.subscribe((ready) => {
thisy = ready;
if (ready && thisnId) {
thisll();
}
}),
callsService$.subscribe((err) => {
this = err;
})
);
}
ngOnDestroy() {
thisp();
subscriptionsh((sub) => subcribe());
}
private async joinCall() {
if (!thisntainer?.nativeElement) return;
thising = true;
this = null;
try {
// Daftarkan event listener sebelum bergabung
thiscribers = [
callsServicentListener("onSessionJoined", () => {
thised = true;
thising = false;
}),
callsServicentListener("onSessionLeft", () => {
thised = false;
navCtrl();
}),
callsServicentListener("onAudioMuted", () => {
thisd = true;
}),
callsServicentListener("onAudioUnMuted", () => {
thisd = false;
}),
callsServicentListener("onVideoPaused", () => {
thisoOff = true;
}),
callsServicentListener("onVideoResumed", () => {
thisoOff = false;
}),
];
// Hasilkan token panggilan untuk sesi ini
const tokenResult = await callsServiceteToken(thisnId);
// Bergabung sesi panggilan
await callsServicession(
tokenResult,
{
sessionType: "VIDEO",
layout: "TILE",
startAudioMuted: false,
startVideoPaused: false,
},
callContainerElement
);
} catch (err: any) {
console("Gagal bergabung panggilan:", err);
this = erre || "Gagal bergabung panggilan";
thising = false;
}
}
toggleAudio() {
thisd ? callsServiceAudio() : callsServicedio();
}
toggleVideo() {
thisoOff ? callsServiceVideo() : callsServiceideo();
}
leaveCall() {
callsServiceession();
}
private cleanup() {
unsubscribersh((unsub) => unsub());
thiscribers = [];
callsServiceession();
}
}Langkah 5: Buat Template Halaman Panggilan
Buat template HTML untuk halaman panggilan dengan kontainer video dan kontrol:
<!-- src/app/pages/call/page -->
<ion-content>
<!-- Status loading -->
<div *ngIf="!isReady" class="loading-container">
<ion-spinner></ion-spinner>
<p>Memulai...</p>
</div>
<!-- Status error -->
<div *ngIf="error" class="error-container">
<ion-icon name="alert-circle" color="danger"></ion-icon>
<p>{{ error }}</p>
<ion-button (click)="joinCall()">Coba Lagi</ion-button>
</div>
<!-- Kontainer video - SDK render UI panggilan di sini -->
<div #callContainer class="call-container" *ngIf="isReady && !error"></div>
<!-- Overlay bergabung -->
<div *ngIf="isJoining" class="joining-overlay">
<ion-spinner></ion-spinner>
<p>Bergabung panggilan...</p>
</div>
<!-- Kontrol panggilan -->
<div class="call-controls" *ngIf="isJoined">
<ion-button
(click)="toggleAudio()"
[color]="isMuted ? 'danger' : 'primary'"
shape="round"
>
<ion-icon slot="icon-only" [name]="isMuted ? 'mic-off' : 'mic'"></ion-icon>
</ion-button>
<ion-button
(click)="toggleVideo()"
[color]="isVideoOff ? 'danger' : 'primary'"
shape="round"
>
<ion-icon slot="icon-only" [name]="isVideoOff ? 'videocam-off' : 'videocam'"></ion-icon>
</ion-button>
<ion-button
(click)="leaveCall()"
color="danger"
shape="round"
>
<ion-icon slot="icon-only" name="call"></ion-icon>
</ion-button>
</div>
</ion-content>/* src/app/pages/call/page */
.call-container {
width: 100%;
height: calc(100% - 80px);
background-color: #1a1a1a;
}
.call-controls {
display: flex;
justify-content: center;
gap: 16px;
padding: 16px;
background-color: #f5f5f5;
}
.loading-container,
.error-container,
.joining-overlay {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
gap: 16px;
}
.joining-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.7);
color: white;
z-index: 100;
}Langkah 6: Buat Halaman Utama
Buat halaman utama di mana pengguna dapat memasukkan ID sesi dan bergabung panggilan:
// src/app/pages/home/page
import { Component } from "@angular/core";
import { Router } from "@angular/router";
import { CometChatCallsService } from "../../services/cometchat-callse";
@Component({
selector: "app-home",
templateUrl: "./page",
})
export class HomePage {
sessionId = "";
isReady$ = callsServicey$;
user$ = callsService$;
error$ = callsService$;
constructor(
private router: Router,
private callsService: CometChatCallsService
) {}
joinCall() {
if (thisnId) {
routerte(["/call", thisnId]);
}
}
}<!-- src/app/pages/home/page -->
<ion-header>
<ion-toolbar>
<ion-title>CometChat Calls</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<div *ngIf="error$ | async as error" class="error-message">
<ion-text color="danger">{{ error }}</ion-text>
</div>
<div *ngIf="!(isReady$ | async)" class="loading">
<ion-spinner></ion-spinner>
<p>Memuat...</p>
</div>
<div *ngIf="isReady$ | async">
<p *ngIf="user$ | async as user">
Masuk sebagai: {{ user || user }}
</p>
<ion-item>
<ion-label position="floating">ID Sesi</ion-label>
<ion-input [(ngModel)]="sessionId" placeholder="Masukkan ID Sesi"></ion-input>
</ion-item>
<ion-button
expand="block"
(click)="joinCall()"
[disabled]="!sessionId"
class="ion-margin-top"
>
Bergabung Panggilan
</ion-button>
</div>
</ion-content>Ionic React
Langkah 2: Buat Provider
Buat context provider yang menangani inisialisasi SDK dan autentikasi:
// src/providers/CometChatCallsProvider
import { createContext, useContext, useEffect, useState, ReactNode } from "react";
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
import { isPlatform } from "@ionic/react";
interface User {
uid: string;
name: string;
avatar?: string;
}
interface CometChatCallsContextType {
isReady: boolean;
user: User | null;
error: string | null;
}
const CometChatCallsContext = createContext<CometChatCallsContextType>({
isReady: false,
user: null,
error: null,
});
// Ganti dengan kredensial CometChat Anda
const APP_ID = "YOUR_APP_ID";
const REGION = "YOUR_REGION";
const API_KEY = "YOUR_API_KEY";
interface ProviderProps {
children: ReactNode;
uid: string;
}
export function CometChatCallsProvider({ children, uid }: ProviderProps) {
const [isReady, setIsReady] = useState(false);
const [user, setUser] = useState<User | null>(null);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
async function initAndLogin() {
try {
// Langkah 1: Inisialisasi SDK
const initResult = await CometChatCalls({
appId: APP_ID,
region: REGION,
});
if (!initResults) {
throw new Error("Inisialisasi SDK gagal");
}
// Langkah 2: Periksa apakah sudah login
let loggedInUser = CometChatCallsgedInUser();
// Langkah 3: Login jika belum
if (!loggedInUser) {
loggedInUser = await CometChatCalls(uid, API_KEY);
}
setUser(loggedInUser);
setIsReady(true);
} catch (err: any) {
console("Pengaturan CometChat Calls gagal:", err);
setError(erre || "Pengaturan gagal");
}
}
if (uid) {
initAndLogin();
}
}, [uid]);
return (
<CometChatCallsContexter value={{ isReady, user, error }}>
{children}
</CometChatCallsContexter>
);
}
export function useCometChatCalls(): CometChatCallsContextType {
return useContext(CometChatCallsContext);
}Langkah 3: Bungkus Aplikasi
Tambahkan provider ke komponen root aplikasi:
// src/App
import { IonApp, IonRouterOutlet, setupIonicReact } from "@ionic/react";
import { IonReactRouter } from "@ionic/react-router";
import { Route } from "react-router-dom";
import { CometChatCallsProvider } from "./providers/CometChatCallsProvider";
import HomePage from "./pages/Home";
import CallPage from "./pages/Call";
setupIonicReact();
const App: React = () => {
// Di aplikasi nyata, ambil dari sistem autentikasi Anda
const currentUserId = "cometchat-uid-1";
return (
<IonApp>
<CometChatCallsProvider uid={currentUserId}>
<IonReactRouter>
<IonRouterOutlet>
<Route exact path="/" component={HomePage} />
<Route exact path="/call/:sessionId" component={CallPage} />
</IonRouterOutlet>
</IonReactRouter>
</CometChatCallsProvider>
</IonApp>
);
};
export default App;Langkah 4: Buat Halaman Panggilan
Buat halaman panggilan yang menangani bergabung sesi, kontrol media, dan pembersihan:
// src/pages/Call
import { useEffect, useRef, useState } from "react";
import {
IonContent,
IonPage,
IonButton,
IonIcon,
IonSpinner,
useIonRouter
} from "@ionic/react";
import { mic, micOff, videocam, videocamOff, call } from "ionicons/icons";
import { useParams } from "react-router-dom";
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
import { useCometChatCalls } from "../providers/CometChatCallsProvider";
const CallPage: React = () => {
const { sessionId } = useParams<{ sessionId: string }>();
const { isReady, error: initError } = useCometChatCalls();
const router = useIonRouter();
const containerRef = useRef<HTMLDivElement>(null);
// Status panggilan
const [isJoined, setIsJoined] = useState(false);
const [isJoining, setIsJoining] = useState(false);
const [isMuted, setIsMuted] = useState(false);
const [isVideoOff, setIsVideoOff] = useState(false);
const [error, setError] = useState<string | null>(null);
const unsubscribersRef = useRef<Function[]>([]);
useEffect(() => {
if (!isReady || !containerReft || !sessionId) return;
async function joinCall() {
setIsJoining(true);
setError(null);
try {
// Daftarkan event listener sebelum bergabung
unsubscribersReft = [
CometChatCallsntListener("onSessionJoined", () => {
setIsJoined(true);
setIsJoining(false);
}),
CometChatCallsntListener("onSessionLeft", () => {
setIsJoined(false);
router();
}),
CometChatCallsntListener("onAudioMuted", () => setIsMuted(true)),
CometChatCallsntListener("onAudioUnMuted", () => setIsMuted(false)),
CometChatCallsntListener("onVideoPaused", () => setIsVideoOff(true)),
CometChatCallsntListener("onVideoResumed", () => setIsVideoOff(false)),
];
// Hasilkan token panggilan untuk sesi ini
const tokenResult = await CometChatCallsteToken(sessionId);
// Bergabung sesi panggilan
await CometChatCallsssion(
tokenResult,
{
sessionType: "VIDEO",
layout: "TILE",
startAudioMuted: false,
startVideoPaused: false,
},
containerReft!
);
} catch (err: any) {
console("Gagal bergabung panggilan:", err);
setError(erre || "Gagal bergabung panggilan");
setIsJoining(false);
}
}
joinCall();
return () => {
currenth((unsub) => unsub());
unsubscribersReft = [];
CometChatCallsession();
};
}, [isReady, sessionId, router]);
// Handler kontrol
const toggleAudio = () => {
isMuted ? CometChatCallsAudio() : CometChatCallsdio();
};
const toggleVideo = () => {
isVideoOff ? CometChatCallsVideo() : CometChatCallsideo();
};
const leaveCall = () => {
CometChatCallsession();
};
// Status loading
if (!isReady) {
return (
<IonPage>
<IonContent className="ion-padding ion-text-center">
<IonSpinner />
<p>Memulai...</p>
</IonContent>
</IonPage>
);
}
// Status error
if (error || initError) {
return (
<IonPage>
<IonContent className="ion-padding ion-text-center">
<p style={{ color: "var(--ion-color-danger)" }}>
Error: {error || initError}
</p>
<IonButton onClick={() => location()}>Coba Lagi</IonButton>
</IonContent>
</IonPage>
);
}
return (
<IonPage>
<IonContent>
{/* Kontainer video - SDK render UI panggilan di sini */}
<div
ref={containerRef}
style={{
width: "100%",
height: "calc(100% - 80px)",
backgroundColor: "#1a1a1a"
}}
/>
{/* Overlay bergabung */}
{isJoining && (
<div style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
backgroundColor: "rgba(0, 0, 0, 0.7)",
color: "white",
zIndex: 100,
}}>
<IonSpinner color="light" />
<p>Bergabung panggilan...</p>
</div>
)}
{/* Kontrol panggilan */}
{isJoined && (
<div style={{
display: "flex",
justifyContent: "center",
gap: "16px",
padding: "16px"
}}>
<IonButton
onClick={toggleAudio}
color={isMuted ? "danger" : "primary"}
shape="round"
>
<IonIcon slot="icon-only" icon={isMuted ? micOff : mic} />
</IonButton>
<IonButton
onClick={toggleVideo}
color={isVideoOff ? "danger" : "primary"}
shape="round"
>
<IonIcon slot="icon-only" icon={isVideoOff ? videocamOff : videocam} />
</IonButton>
<IonButton
onClick={leaveCall}
color="danger"
shape="round"
>
<IonIcon slot="icon-only" icon={call} />
</IonButton>
</div>
)}
</IonContent>
</IonPage>
);
};
export default CallPage;Langkah 5: Buat Halaman Utama
Buat halaman utama di mana pengguna dapat memasukkan ID sesi dan bergabung panggilan:
// src/pages/Home
import { useState } from "react";
import {
IonContent,
IonPage,
IonHeader,
IonToolbar,
IonTitle,
IonItem,
IonLabel,
IonInput,
IonButton,
IonSpinner,
IonText,
useIonRouter
} from "@ionic/react";
import { useCometChatCalls } from "../providers/CometChatCallsProvider";
const HomePage: React = () => {
const { isReady, user, error } = useCometChatCalls();
const router = useIonRouter();
const [sessionId, setSessionId] = useState("");
const joinCall = () => {
if (sessionId) {
router(`/call/${sessionId}`);
}
};
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>CometChat Calls</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">
{error && (
<IonText color="danger">
<p>{error}</p>
</IonText>
)}
{!isReady ? (
<div className="ion-text-center">
<IonSpinner />
<p>Memuat...</p>
</div>
) : (
<>
<p>Masuk sebagai: {user?.name || user?.uid}</p>
<IonItem>
<IonLabel position="floating">ID Sesi</IonLabel>
<IonInput
value={sessionId}
onIonChange={(e) => setSessionId(detail || "")}
placeholder="Masukkan ID Sesi"
/>
</IonItem>
<IonButton
expand="block"
onClick={joinCall}
disabled={!sessionId}
className="ion-margin-top"
>
Bergabung Panggilan
</IonButton>
</>
)}
</IonContent>
</IonPage>
);
};
export default HomePage;Ionic Vue
Langkah 2: Buat Composable
Buat composable yang menangani inisialisasi SDK dan autentikasi:
// src/composables/useCometChatCalls
import { ref, readonly } from "vue";
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
interface User {
uid: string;
name: string;
avatar?: string;
}
// Ganti dengan kredensial CometChat Anda
const APP_ID = "YOUR_APP_ID";
const REGION = "YOUR_REGION";
const API_KEY = "YOUR_API_KEY";
// State bersama untuk semua komponen
const isReady = ref(false);
const user = ref<User | null>(null);
const error = ref<string | null>(null);
const initialized = ref(false);
export function useCometChatCalls() {
async function initAndLogin(uid: string): Promise<boolean> {
if (initialized) {
return isReady;
}
try {
// Langkah 1: Inisialisasi SDK
const initResult = await CometChatCalls({
appId: APP_ID,
region: REGION,
});
if (!initResults) {
throw new Error("Inisialisasi SDK gagal");
}
// Langkah 2: Periksa apakah sudah login
let loggedInUser = CometChatCallsgedInUser();
// Langkah 3: Login jika belum
if (!loggedInUser) {
loggedInUser = await CometChatCalls(uid, API_KEY);
}
user = loggedInUser;
isReady = true;
initialized = true;
return true;
} catch (err: any) {
console("Pengaturan CometChat Calls gagal:", err);
error = erre || "Pengaturan gagal";
return false;
}
}
return {
isReady: readonly(isReady),
user: readonly(user),
error: readonly(error),
initAndLogin,
};
}Langkah 3: Inisialisasi di App Component
Inisialisasi SDK dan login saat aplikasi dimulai:
<!-- src/App -->
<template>
<ion-app>
<ion-router-outlet />
</ion-app>
</template>
<script setup lang="ts">
import { IonApp, IonRouterOutlet } from "@ionic/vue";
import { onMounted } from "vue";
import { useCometChatCalls } from "./composables/useCometChatCalls";
const { initAndLogin } = useCometChatCalls();
onMounted(() => {
// Di aplikasi nyata, ambil dari sistem autentikasi Anda
const currentUserId = "cometchat-uid-1";
initAndLogin(currentUserId);
});
</script>Langkah 4: Buat Halaman Panggilan
Buat halaman panggilan yang menangani bergabung sesi, kontrol media, dan pembersihan:
<!-- src/views/CallPage -->
<template>
<ion-page>
<ion-content>
<!-- Status loading -->
<div v-if="!isReady" class="loading-container">
<ion-spinner></ion-spinner>
<p>Memulai...</p>
</div>
<!-- Status error -->
<div v-else-if="callError" class="error-container">
<ion-text color="danger">{{ callError }}</ion-text>
<ion-button @click="joinCall">Coba Lagi</ion-button>
</div>
<!-- Kontainer video - SDK render UI panggilan di sini -->
<div v-else ref="callContainer" class="call-container"></div>
<!-- Overlay bergabung -->
<div v-if="isJoining" class="joining-overlay">
<ion-spinner color="light"></ion-spinner>
<p>Bergabung panggilan...</p>
</div>
<!-- Kontrol panggilan -->
<div v-if="isJoined" class="call-controls">
<ion-button
@click="toggleAudio"
:color="isMuted ? 'danger' : 'primary'"
shape="round"
>
<ion-icon slot="icon-only" :icon="isMuted ? micOff : mic"></ion-icon>
</ion-button>
<ion-button
@click="toggleVideo"
:color="isVideoOff ? 'danger' : 'primary'"
shape="round"
>
<ion-icon slot="icon-only" :icon="isVideoOff ? videocamOff : videocam"></ion-icon>
</ion-button>
<ion-button
@click="leaveCall"
color="danger"
shape="round"
>
<ion-icon slot="icon-only" :icon="call"></ion-icon>
</ion-button>
</div>
</ion-content>
</ion-page>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import {
IonPage,
IonContent,
IonButton,
IonIcon,
IonSpinner,
IonText
} from "@ionic/vue";
import { mic, micOff, videocam, videocamOff, call } from "ionicons/icons";
import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
import { useCometChatCalls } from "../composables/useCometChatCalls";
const route = useRoute();
const router = useRouter();
const sessionId = paramsnId as string;
const { isReady } = useCometChatCalls();
// Ref template
const callContainer = ref<HTMLDivElement | null>(null);
// Status panggilan
const isJoined = ref(false);
const isJoining = ref(false);
const isMuted = ref(false);
const isVideoOff = ref(false);
const callError = ref<string | null>(null);
// Simpan fungsi unsubscribe untuk pembersihan
const unsubscribers = ref<Function[]>([]);
async function joinCall() {
if (!callContainer || !sessionId) return;
isJoining = true;
callError = null;
try {
// Daftarkan event listener sebelum bergabung
unsubscribers = [
CometChatCallsntListener("onSessionJoined", () => {
isJoined = true;
isJoining = false;
}),
CometChatCallsntListener("onSessionLeft", () => {
isJoined = false;
router();
}),
CometChatCallsntListener("onAudioMuted", () => {
isMuted = true;
}),
CometChatCallsntListener("onAudioUnMuted", () => {
isMuted = false;
}),
CometChatCallsntListener("onVideoPaused", () => {
isVideoOff = true;
}),
CometChatCallsntListener("onVideoResumed", () => {
isVideoOff = false;
}),
];
// Hasilkan token panggilan untuk sesi ini
const tokenResult = await CometChatCallsteToken(sessionId);
// Bergabung sesi panggilan
await CometChatCallsssion(
tokenResult,
{
sessionType: "VIDEO",
layout: "TILE",
startAudioMuted: false,
startVideoPaused: false,
},
callContainer
);
} catch (err: any) {
console("Gagal bergabung panggilan:", err);
callError = erre || "Gagal bergabung panggilan";
isJoining = false;
}
}
function toggleAudio() {
isMuted ? CometChatCallsAudio() : CometChatCallsdio();
}
function toggleVideo() {
isVideoOff ? CometChatCallsVideo() : CometChatCallsideo();
}
function leaveCall() {
CometChatCallsession();
}
function cleanup() {
valueh((unsub) => unsub());
unsubscribers = [];
CometChatCallsession();
}
// Pantau status SDK dan bergabung saat siap
watch(isReady, (ready) => {
if (ready && callContainer) {
joinCall();
}
});
onMounted(() => {
if (isReady && callContainer) {
joinCall();
}
});
onUnmounted(() => {
cleanup();
});
</script>
<style scoped>
.call-container {
width: 100%;
height: calc(100% - 80px);
background-color: #1a1a1a;
}
.call-controls {
display: flex;
justify-content: center;
gap: 16px;
padding: 16px;
}
.loading-container,
.error-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
gap: 16px;
}
.joining-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.7);
color: white;
z-index: 100;
}
</style>Langkah 5: Buat Halaman Utama
Buat halaman utama di mana pengguna dapat memasukkan ID sesi dan bergabung panggilan:
<!-- src/views/HomePage -->
<template>
<ion-page>
<ion-header>
<ion-toolbar>
<ion-title>CometChat Calls</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-text v-if="error" color="danger">
<p>{{ error }}</p>
</ion-text>
<div v-if="!isReady" class="ion-text-center">
<ion-spinner></ion-spinner>
<p>Memuat...</p>
</div>
<template v-else>
<p>Masuk sebagai: {{ user?.name || user?.uid }}</p>
<ion-item>
<ion-label position="floating">ID Sesi</ion-label>
<ion-input
v-model="sessionId"
placeholder="Masukkan ID Sesi"
></ion-input>
</ion-item>
<ion-button
expand="block"
@click="joinCall"
:disabled="!sessionId"
class="ion-margin-top"
>
Bergabung Panggilan
</ion-button>
</template>
</ion-content>
</ion-page>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useRouter } from "vue-router";
import {
IonPage,
IonHeader,
IonToolbar,
IonTitle,
IonContent,
IonItem,
IonLabel,
IonInput,
IonButton,
IonSpinner,
IonText
} from "@ionic/vue";
import { useCometChatCalls } from "../composables/useCometChatCalls";
const router = useRouter();
const { isReady, user, error } = useCometChatCalls();
const sessionId = ref("");
function joinCall() {
if (sessionId) {
router(`/call/${sessionId}`);
}
}
</script>Langkah 6: Konfigurasi Routes
Atur router dengan halaman utama dan halaman panggilan:
// src/router/index
import { createRouter, createWebHistory } from "@ionic/vue-router";
import { RouteRecordRaw } from "vue-router";
import HomePage from "../views/HomePage";
import CallPage from "../views/CallPage";
const routes: Array<RouteRecordRaw> = [
{
path: "/",
component: HomePage,
},
{
path: "/call/:sessionId",
component: CallPage,
},
];
const router = createRouter({
history: createWebHistory(env_URL),
routes,
});
export default router;
Platform Lainnya
Berita Piala Dunia
Jika Anda memiliki pertanyaan, silakan kirim email ke [email protected]