roomkit-web-vue3
Version:
<h1 align="center"> TUIRoomKit</h1> Conference (TUIRoomKit) is a product suitable for multi-person audio and video conversation scenarios such as business meetings, webinars, and online education. By integrating this product, you can add room management,
300 lines (299 loc) • 12.2 kB
JavaScript
import { defineComponent, ref, watch, computed, onBeforeUnmount, openBlock, createElementBlock, createElementVNode, createVNode, unref, normalizeClass, toDisplayString, createCommentVNode, withCtx, createTextVNode } from "vue";
import { isMobile } from "../../../utils/environment.mjs";
import IconButton from "../../common/base/IconButton.vue.mjs";
import SvgIcon from "../../common/base/SvgIcon.vue.mjs";
import StepDownIcon from "../../common/icons/StepDownIcon.vue.mjs";
import ApplyStageIcon from "../../common/icons/ApplyStageIcon.vue.mjs";
import CancelStageIcon from "../../common/icons/CancelStageIcon.vue.mjs";
import CloseIcon from "../../common/icons/CloseIcon.vue.mjs";
import Dialog from "../../common/base/Dialog/index.mjs";
import renderMsg from "../../common/base/Message/Message.mjs";
import { MESSAGE_DURATION } from "../../../constants/message.mjs";
import { useBasicStore } from "../../../stores/basic.mjs";
import { useRoomStore } from "../../../stores/room.mjs";
import { useI18n } from "../../../locales/index.mjs";
import { storeToRefs } from "pinia";
import useRoomEngine from "../../../hooks/useRoomEngine.mjs";
import logger from "../../../utils/common/logger/index.mjs";
import TUIRoomEngine__default, { TUIRole, TUIErrorCode, TUIRoomEvents, TUIRequestAction, TUIRequestCallbackType } from "@tencentcloud/tuiroom-engine-js";
import { TUIButton } from "@tencentcloud/uikit-base-component-vue3";
import { debounce } from "../../../utils/utils.mjs";
const _hoisted_1 = { class: "apply-control-container" };
const _hoisted_2 = {
key: 0,
class: "attention member-attention"
};
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "MemberApplyControl",
setup(__props) {
const roomEngine = useRoomEngine();
const { t } = useI18n();
const basicStore = useBasicStore();
const roomStore = useRoomStore();
const { lang } = storeToRefs(basicStore);
const { localUser, isGeneralUser, isAdmin } = storeToRefs(roomStore);
const isApplyingOnSeat = ref(false);
const showMemberApplyAttention = ref(true);
const iconName = ref();
const iconTitle = ref("");
const applyToAnchorRequestId = ref("");
const inviteToAnchorRequestId = ref("");
const showDialog = ref(false);
const currentDialogTitle = ref("");
const currentConfirmButton = ref("");
const currentDialogType = ref("inviteDialog");
watch(
[localUser, isApplyingOnSeat, lang],
([localUser2, isApplyingOnSeat2]) => {
if (localUser2.onSeat) {
iconName.value = StepDownIcon;
iconTitle.value = t("Step down");
hideApplyAttention();
} else {
if (isApplyingOnSeat2) {
iconName.value = CancelStageIcon;
iconTitle.value = t("Cancel Apply");
} else {
iconName.value = ApplyStageIcon;
iconTitle.value = t("Apply for the stage");
}
}
},
{ immediate: true, deep: true }
);
const toggleApplySpeechDebounce = debounce(toggleApplySpeech, 300);
async function toggleApplySpeech() {
hideApplyAttention();
if (localUser.value.onSeat) {
handleStepDownDialogVisible();
} else {
isApplyingOnSeat.value ? cancelSeatApplication() : sendSeatApplication();
}
}
const inviteDialogInfo = computed(() => ({
content: t("You can turn on the microphone and camera once you are on stage"),
confirmButtonText: t("Agree to the stage"),
cancelButtonText: t("Reject"),
handleConfirm: () => handleInvite(true),
handleCancel: () => handleInvite(false)
}));
const leaveSeatDialogInfo = computed(() => ({
content: localUser.value.userRole === TUIRole.kAdministrator ? t("To go on stage again, a new application needs to be initiated") : t(
"To go on stage again, you need to reapply and wait for the roomOwner/administrator to approve"
),
confirmButtonText: t("Step down"),
cancelButtonText: t("Cancel"),
handleConfirm: () => leaveSeat(),
handleCancel: () => handleStepDownDialogVisible()
}));
const currentDialogInfo = computed(
() => currentDialogType.value === "inviteDialog" ? inviteDialogInfo.value : leaveSeatDialogInfo.value
);
async function sendSeatApplication() {
var _a, _b;
if (isAdmin.value) {
await ((_a = roomEngine.instance) == null ? void 0 : _a.takeSeat({ seatIndex: -1, timeout: 0 }));
renderMsg({ type: "success", message: t("Succeed on stage") });
return;
}
if (isGeneralUser.value) {
renderMsg({
type: "info",
message: `${t("The request to go on stage has been sent out, please wait for the roomOwner/administrator to approve it")}`,
duration: MESSAGE_DURATION.NORMAL
});
}
const request = await ((_b = roomEngine.instance) == null ? void 0 : _b.takeSeat({
seatIndex: -1,
timeout: 60,
requestCallback: (callbackInfo) => {
isApplyingOnSeat.value = false;
const { requestCallbackType } = callbackInfo;
switch (requestCallbackType) {
case TUIRequestCallbackType.kRequestAccepted:
renderMsg({ type: "success", message: t("Succeed on stage") });
break;
case TUIRequestCallbackType.kRequestRejected:
renderMsg({
type: "warning",
message: t("Application to go on stage was rejected")
});
break;
case TUIRequestCallbackType.kRequestTimeout:
renderMsg({
type: "warning",
message: t("The request to go on stage has timed out")
});
break;
}
}
}));
if (request && request.requestId) {
applyToAnchorRequestId.value = request.requestId;
}
isApplyingOnSeat.value = true;
}
async function cancelSeatApplication() {
var _a;
renderMsg({
type: "info",
message: `${t("Canceled application to go on stage")}`,
duration: MESSAGE_DURATION.NORMAL
});
try {
await ((_a = roomEngine.instance) == null ? void 0 : _a.cancelRequest({
requestId: applyToAnchorRequestId.value
}));
isApplyingOnSeat.value = false;
} catch (error) {
logger.log("member cancelSpeechApplication", error);
}
}
function handleStepDownDialogVisible() {
showDialog.value = !showDialog.value;
currentDialogType.value = "leaveSeatDialog";
currentDialogTitle.value = t("Are you sure you want to step down");
}
async function leaveSeat() {
var _a;
await ((_a = roomEngine.instance) == null ? void 0 : _a.leaveSeat());
showDialog.value = false;
}
function hideApplyAttention() {
showMemberApplyAttention.value = false;
}
async function onRequestReceived(eventInfo) {
const {
request: { userId, requestId, requestAction }
} = eventInfo;
if (requestAction === TUIRequestAction.kRequestRemoteUserOnSeat) {
inviteToAnchorRequestId.value = requestId;
const userRole = roomStore.getUserRole(userId) === TUIRole.kRoomOwner ? t("RoomOwner") : t("Admin");
currentDialogTitle.value = t("Sb invites you to speak on stage", {
role: userRole
});
currentConfirmButton.value = t("Agree to the stage");
showDialog.value = true;
currentDialogType.value = "inviteDialog";
}
}
function onRequestCancelled(eventInfo) {
const { requestId } = eventInfo;
if (inviteToAnchorRequestId.value === requestId) {
inviteToAnchorRequestId.value = "";
showDialog.value = false;
}
}
async function handleInvite(agree) {
var _a;
try {
await ((_a = roomEngine.instance) == null ? void 0 : _a.responseRemoteRequest({
requestId: inviteToAnchorRequestId.value,
agree
}));
} catch (error) {
if (error.code === TUIErrorCode.ERR_ALL_SEAT_OCCUPIED) {
renderMsg({
type: "warning",
message: t("The stage is full, please contact the host")
});
} else {
logger.error(
"Failure of a user to accept/reject a roomOwner invitation",
error
);
}
} finally {
showDialog.value = false;
}
}
async function onKickedOffSeat() {
renderMsg({
type: "warning",
message: t(
"You have been invited by the host to step down, please raise your hand if you need to speak"
),
duration: MESSAGE_DURATION.NORMAL
});
}
TUIRoomEngine__default.once("ready", () => {
var _a, _b, _c;
(_a = roomEngine.instance) == null ? void 0 : _a.on(TUIRoomEvents.onRequestReceived, onRequestReceived);
(_b = roomEngine.instance) == null ? void 0 : _b.on(TUIRoomEvents.onRequestCancelled, onRequestCancelled);
(_c = roomEngine.instance) == null ? void 0 : _c.on(TUIRoomEvents.onKickedOffSeat, onKickedOffSeat);
});
onBeforeUnmount(() => {
var _a, _b, _c;
(_a = roomEngine.instance) == null ? void 0 : _a.off(TUIRoomEvents.onRequestReceived, onRequestReceived);
(_b = roomEngine.instance) == null ? void 0 : _b.off(
TUIRoomEvents.onRequestCancelled,
onRequestCancelled
);
(_c = roomEngine.instance) == null ? void 0 : _c.off(TUIRoomEvents.onKickedOffSeat, onKickedOffSeat);
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", null, [
createElementVNode("div", _hoisted_1, [
createVNode(IconButton, {
title: iconTitle.value,
icon: iconName.value,
onClickIcon: unref(toggleApplySpeechDebounce)
}, null, 8, ["title", "icon", "onClickIcon"]),
showMemberApplyAttention.value ? (openBlock(), createElementBlock("div", _hoisted_2, [
createElementVNode("span", {
class: normalizeClass(unref(isMobile) ? "mobile-info" : "info")
}, toDisplayString(unref(t)("Please raise your hand to apply")), 3),
createVNode(SvgIcon, {
icon: CloseIcon,
class: "close",
onClick: hideApplyAttention
})
])) : createCommentVNode("", true)
]),
createVNode(unref(Dialog), {
modelValue: showDialog.value,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => showDialog.value = $event),
title: currentDialogTitle.value,
modal: true,
"show-close": false,
"close-on-click-modal": false,
width: "500px",
"append-to-room-container": true,
"confirm-button": currentDialogInfo.value.confirmButtonText,
"cancel-button": currentDialogInfo.value.cancelButtonText,
onConfirm: currentDialogInfo.value.handleConfirm,
onCancel: currentDialogInfo.value.handleCancel
}, {
footer: withCtx(() => [
createVNode(unref(TUIButton), {
onClick: currentDialogInfo.value.handleConfirm,
type: "default",
style: { "min-width": "88px" }
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(currentDialogInfo.value.confirmButtonText), 1)
]),
_: 1
}, 8, ["onClick"]),
createVNode(unref(TUIButton), {
onClick: currentDialogInfo.value.handleCancel,
style: { "min-width": "88px" }
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(currentDialogInfo.value.cancelButtonText), 1)
]),
_: 1
}, 8, ["onClick"])
]),
default: withCtx(() => [
createElementVNode("span", null, toDisplayString(currentDialogInfo.value.content), 1)
]),
_: 1
}, 8, ["modelValue", "title", "confirm-button", "cancel-button", "onConfirm", "onCancel"])
]);
};
}
});
export {
_sfc_main as default
};