@tencentcloud/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,
660 lines (659 loc) • 26.1 kB
JavaScript
import { defineComponent, ref, computed, createElementBlock, openBlock, withDirectives, createVNode, createElementVNode, createBlock, createCommentVNode, toDisplayString, unref, normalizeClass, Fragment, renderList, vShow, withCtx, createTextVNode, createSlots, withModifiers, nextTick } from "vue";
import { TUIConferenceStatus } from "@tencentcloud/tuiroom-engine-js";
import "../../services/main.mjs";
import { roomService } from "../../services/roomService.mjs";
import logger from "../../utils/common/logger/index.mjs";
import { useI18n } from "../../locales/index.mjs";
import { isMobile } from "../../utils/environment.mjs";
import { convertSecondsToHMS, getUrlWithRoomId } from "../../utils/utils.mjs";
import "mitt";
import "../../services/manager/roomActionManager.mjs";
import "@tencentcloud/tui-core";
import useRoomInfo from "../RoomHeader/RoomInfo/useRoomInfoHooks.mjs";
import Dialog from "../common/base/Dialog/index.mjs";
import { IconChevronRight, IconEllipsis, IconLink, TUIButton, IconArrowDown, IconWarning, IconSuccess } from "@tencentcloud/uikit-base-component-vue3";
import vClickOutside from "../../directives/vClickOutside.mjs";
import ScheduleConferencePanel from "./ScheduleConferencePanel/index.mjs";
import { useBasicStore } from "../../stores/basic.mjs";
import { storeToRefs } from "pinia";
import ConferenceDetail from "./ConferenceDetail.vue.mjs";
import InvitePanel from "./InvitePanel.vue.mjs";
import PanelContainer from "./PanelContainer.vue.mjs";
const _hoisted_1 = { class: "schedule-room-control" };
const _hoisted_2 = ["title"];
const _hoisted_3 = { class: "schedule-title-text" };
const _hoisted_4 = { class: "schedule-content" };
const _hoisted_5 = { class: "schedule-content-time" };
const _hoisted_6 = { class: "schedule-content-room-id" };
const _hoisted_7 = {
key: 0,
class: "segregation-vertical"
};
const _hoisted_8 = ["onClick"];
const _hoisted_9 = ["onClick"];
const _hoisted_10 = { class: "room-detail-content" };
const _hoisted_11 = {
key: 0,
class: "room-detail h5"
};
const _hoisted_12 = { class: "detail-footer" };
const _hoisted_13 = {
key: 1,
class: "invite-member-panel"
};
const _hoisted_14 = { class: "invite-member-header" };
const _hoisted_15 = { key: 1 };
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "ScheduleRoomControl",
props: {
item: {},
scheduleStartDate: {},
scheduleEndDate: {},
scheduleStartTime: {},
scheduleEndTime: {}
},
emits: ["join-conference", "show-more"],
setup(__props, { emit: __emit }) {
const basicStore = useBasicStore();
const { userId, userName, isRoomLinkVisible } = storeToRefs(basicStore);
const roomLinkConfig = roomService.getComponentConfig("RoomLink");
const { t } = useI18n();
const showMoreControl = ref(false);
const dropdownClass = ref("down");
const moreBtnRef = ref();
const operateListRef = ref();
const modifyDialogVisible = ref(false);
const emit = __emit;
const showRoomDetail = ref(false);
const showRoomCancel = ref(false);
const showRoomInvite = ref(false);
const roomInfo = ref();
const props = __props;
const { onCopy } = useRoomInfo();
const statusMap = {
[TUIConferenceStatus.kConferenceStatusRunning]: {
text: "Ongoing",
className: "status-running"
}
};
const getStatusTextAndClass = (status) => statusMap[status] || { text: "", className: "" };
const isOwner = computed(
() => props.item.basicRoomInfo.ownerId === roomService.basicStore.userId && props.item.status === TUIConferenceStatus.kConferenceStatusNotStarted
);
const isShowPassword = computed(() => {
var _a;
return !!((_a = roomInfo.value) == null ? void 0 : _a.password);
});
const viewDetails = computed(() => ({
key: "roomDetails",
title: t("view details"),
visible: true,
func: () => {
showRoomDetail.value = true;
showMoreControl.value = false;
}
}));
const modifyRoom = computed(() => ({
key: "modifyRoom",
title: t("modify room"),
visible: isOwner.value,
func: () => {
modifyDialogVisible.value = true;
showMoreControl.value = false;
}
}));
const cancelRoom = computed(() => ({
key: "cancelRoom",
title: t("cancel room"),
visible: isOwner.value,
func: () => {
showRoomCancel.value = true;
showMoreControl.value = false;
}
}));
const moreControlList = computed(() => [
viewDetails.value,
modifyRoom.value,
cancelRoom.value
]);
const scheduleAttendeesInfo = computed(
() => props.item.scheduleAttendees ? props.item.scheduleAttendees.map(
(attendee) => attendee.userName || attendee.userId
).join("; ") : ""
);
const durationTime = computed(
() => props.item.scheduleEndTime - props.item.scheduleStartTime
);
function getScheduleTime(timestamp) {
const date = new Date(timestamp);
const hours = `${date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()}`;
const minutes = `${date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes()}`;
return `${hours}:${minutes}`;
}
const scheduleRoomDetailList = computed(() => {
var _a;
const { hours, minutes } = convertSecondsToHMS(
props.item.scheduleEndTime - props.item.scheduleStartTime
);
return [
{
title: "Room Name",
content: props.item.basicRoomInfo.roomName,
isShowCopyIcon: false,
status: null,
isShowStatus: false,
isVisible: true
},
{
title: "Room ID",
content: props.item.basicRoomInfo.roomId,
isShowCopyIcon: true,
status: null,
isShowStatus: false,
isVisible: true
},
{
title: "Room Time",
content: `${props.scheduleStartDate} ${props.scheduleStartTime} - ${props.scheduleEndDate} ${props.scheduleEndTime}`,
isShowCopyIcon: false,
status: props.item.status,
isShowStatus: true,
isVisible: !isMobile
},
{
title: "Starting time",
content: `${props.scheduleStartDate} ${props.scheduleStartTime}`,
isShowCopyIcon: false,
status: null,
isShowStatus: false,
isVisible: isMobile
},
{
title: "Room duration",
content: hours ? `${hours}${t("hours")}${minutes ? ` ${minutes}${t("minutes")}` : ""}` : `${minutes}${t("minutes")}`,
isShowCopyIcon: false,
status: null,
isShowStatus: false,
isVisible: isMobile
},
{
title: "Room Type",
content: `${t(getSeatModeDisplay(props.item.basicRoomInfo.isSeatEnabled))}`,
isShowCopyIcon: false,
status: null,
isShowStatus: false,
isVisible: true
},
{
title: "Room Password",
content: `${(_a = roomInfo.value) == null ? void 0 : _a.password}`,
isShowCopyIcon: true,
status: null,
isShowStatus: false,
isVisible: isShowPassword.value
},
{
title: "Creator",
content: props.item.basicRoomInfo.roomOwner,
isShowCopyIcon: false,
status: null,
isShowStatus: false,
isVisible: true
},
{
title: "Participants",
content: scheduleAttendeesInfo.value,
isShowCopyIcon: false,
status: null,
isShowStatus: false,
isVisible: true
},
{
title: "Entry Time",
content: `${props.scheduleStartDate}${props.scheduleStartTime}`,
isShowCopyIcon: false,
status: null,
isShowStatus: false,
isVisible: props.item.status === TUIConferenceStatus.kConferenceStatusNone
},
{
title: "Duration of participation",
content: getScheduleTime(durationTime.value),
isShowCopyIcon: false,
status: null,
isShowStatus: false,
isVisible: props.item.status === TUIConferenceStatus.kConferenceStatusNone
}
];
});
const scheduleInviteList = computed(() => {
var _a;
return [
{
title: "Room Name",
content: props.item.basicRoomInfo.roomName,
isShowCopyIcon: false,
isVisible: true
},
{
title: "Room Type",
content: `${t(getSeatModeDisplay(props.item.basicRoomInfo.isSeatEnabled))}`,
isShowCopyIcon: false,
isVisible: true
},
{
title: "Room Time",
content: !isMobile ? `${props.scheduleStartDate} ${props.scheduleStartTime} - ${props.scheduleEndDate} ${props.scheduleEndTime}` : `${props.scheduleStartDate} ${props.scheduleStartTime} - ${props.scheduleEndTime}`,
isShowCopyIcon: false,
isVisible: true
},
{
title: "Room ID",
content: props.item.basicRoomInfo.roomId,
isShowCopyIcon: true,
isVisible: true
},
{
title: "Room Password",
content: `${(_a = roomInfo.value) == null ? void 0 : _a.password}`,
isShowCopyIcon: true,
isVisible: isShowPassword.value
},
{
title: "Room Link",
content: getUrlWithRoomId(props.item.basicRoomInfo.roomId),
isShowCopyIcon: isMobile,
isVisible: isRoomLinkVisible.value && roomLinkConfig.visible
}
];
});
function getSeatModeDisplay(isSeatEnabled) {
return isSeatEnabled ? "On-stage Speaking Room" : "Free Speech Room";
}
async function toggleClickMoreBtn() {
emit("show-more", { roomId: props.item.basicRoomInfo.roomId });
if (!showMoreControl.value) {
await handleDropDownPosition();
}
handleFetchRoomInfo();
showMoreControl.value = !showMoreControl.value;
}
function handleCloseOperate() {
showMoreControl.value = false;
}
async function handleDropDownPosition() {
var _a, _b, _c;
await nextTick();
const { top, bottom } = ((_a = moreBtnRef.value) == null ? void 0 : _a.getBoundingClientRect()) || {};
const { top: containerTop, bottom: containerBottom } = (_b = document.getElementById("scheduleRoomContainer")) == null ? void 0 : _b.getBoundingClientRect();
if (!containerBottom || !containerTop) {
return;
}
const bottomSize = containerBottom - bottom;
const topSize = top - containerTop;
let dropDownContainerHeight = 0;
if (!showMoreControl.value) {
operateListRef.value.style = "display:block;position:absolute;z-index:-1000";
await nextTick();
dropDownContainerHeight = operateListRef.value.offsetHeight;
operateListRef.value.style = "";
} else {
dropDownContainerHeight = (_c = operateListRef.value) == null ? void 0 : _c.offsetHeight;
}
if (topSize < dropDownContainerHeight) {
return;
}
if (bottomSize < dropDownContainerHeight) {
dropdownClass.value = "up";
}
}
const invitePanelShow = ref(false);
const joinConference = () => {
var _a;
emit("join-conference", {
roomId: (_a = props.item) == null ? void 0 : _a.basicRoomInfo.roomId,
roomParam: {
isOpenCamera: false,
isOpenMicrophone: true
}
});
};
const toggleInvitePanelShow = () => {
invitePanelShow.value = !invitePanelShow.value;
};
const showDetail = () => {
if (!isMobile) return;
handleFetchRoomInfo();
emit("show-more", { roomId: props.item.basicRoomInfo.roomId });
viewDetails.value.func();
};
function toggleInviteRoom() {
if (showRoomDetail.value) {
showRoomDetail.value = false;
}
handleFetchRoomInfo();
showRoomInvite.value = !showRoomInvite.value;
}
function copyRoomIdAndRoomLink() {
var _a;
const invitationList = [
`${props.item.basicRoomInfo.roomName}`,
`${t("Room Type")}: ${t(getSeatModeDisplay(props.item.basicRoomInfo.isSeatEnabled))}`,
`${t("Room ID")}: ${props.item.basicRoomInfo.roomId}`
];
if (isShowPassword.value) {
invitationList.push(`${t("Room Password")}: ${(_a = roomInfo.value) == null ? void 0 : _a.password}`);
}
if (isRoomLinkVisible.value && roomLinkConfig.visible) {
invitationList.push(
`${t("Room Link")}: ${getUrlWithRoomId(props.item.basicRoomInfo.roomId)}`
);
}
const invitation = invitationList.join("\n");
onCopy(invitation);
}
async function handleCancelSchedule() {
await roomService.scheduleConferenceManager.cancelConference({
roomId: props.item.basicRoomInfo.roomId
});
showRoomCancel.value = false;
showRoomDetail.value = false;
}
async function handleFetchRoomInfo() {
if (roomInfo.value) {
return;
}
try {
const roomInfoParams = {
roomId: props.item.basicRoomInfo.roomId,
roomType: props.item.basicRoomInfo.roomType
};
roomInfo.value = await roomService.fetchRoomInfo(roomInfoParams);
} catch (error) {
logger.error("fetch roomInfo failed:", error);
}
}
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", null, [
withDirectives((openBlock(), createElementBlock("div", _hoisted_1, [
createElementVNode("div", {
class: "schedule-room-info",
onClick: showDetail
}, [
createElementVNode("div", {
class: "schedule-title",
title: _ctx.item.basicRoomInfo.roomName
}, [
createElementVNode("span", _hoisted_3, toDisplayString(_ctx.item.basicRoomInfo.roomName), 1),
unref(isMobile) ? (openBlock(), createBlock(unref(IconChevronRight), {
key: 0,
class: "schedule-title-icon",
size: "10"
})) : createCommentVNode("", true)
], 8, _hoisted_2),
createElementVNode("div", _hoisted_4, [
createElementVNode("span", _hoisted_5, [
createElementVNode("span", null, toDisplayString(props.scheduleStartTime), 1),
_cache[7] || (_cache[7] = createElementVNode("i", { class: "segregation-level" }, null, -1)),
createElementVNode("span", null, toDisplayString(props.scheduleEndTime), 1)
]),
_cache[8] || (_cache[8] = createElementVNode("i", { class: "segregation-vertical" }, null, -1)),
createElementVNode("span", _hoisted_6, toDisplayString(_ctx.item.basicRoomInfo.roomId), 1),
_ctx.item.status === unref(TUIConferenceStatus).kConferenceStatusRunning ? (openBlock(), createElementBlock("i", _hoisted_7)) : createCommentVNode("", true),
createElementVNode("span", {
class: normalizeClass(["schedule-content-status", getStatusTextAndClass(_ctx.item.status).className])
}, toDisplayString(unref(t)(getStatusTextAndClass(_ctx.item.status).text)), 3)
])
]),
createElementVNode("div", {
ref_key: "moreBtnRef",
ref: moreBtnRef,
class: "schedule-room-operate"
}, [
!unref(isMobile) ? (openBlock(), createBlock(unref(IconEllipsis), {
key: 0,
class: "ellipsis",
onClick: toggleClickMoreBtn,
size: "13"
})) : createCommentVNode("", true),
withDirectives(createElementVNode("div", {
ref_key: "operateListRef",
ref: operateListRef,
class: normalizeClass([
"operate-list",
dropdownClass.value,
!showMoreControl.value ? "hidden" : ""
])
}, [
(openBlock(true), createElementBlock(Fragment, null, renderList(moreControlList.value, (controlItem) => {
return openBlock(), createElementBlock(Fragment, null, [
controlItem.visible ? (openBlock(), createElementBlock("div", {
key: controlItem.key,
class: normalizeClass(["operate-item", { "cancel-text": controlItem.key === "cancelRoom" }]),
onClick: ($event) => controlItem.func()
}, [
createElementVNode("span", {
class: "operate-text",
onClick: controlItem.func
}, toDisplayString(controlItem.title), 9, _hoisted_9)
], 10, _hoisted_8)) : createCommentVNode("", true)
], 64);
}), 256))
], 2), [
[vShow, showMoreControl.value]
]),
!unref(isMobile) ? (openBlock(), createBlock(unref(IconLink), {
key: 1,
size: "13",
class: "link",
onClick: toggleInviteRoom
})) : createCommentVNode("", true),
createVNode(unref(TUIButton), {
onClick: joinConference,
type: "primary"
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(t)("Join")), 1)
]),
_: 1
})
], 512)
])), [
[unref(vClickOutside), handleCloseOperate]
]),
createVNode(PanelContainer, {
visible: showRoomDetail.value,
onInput: _cache[0] || (_cache[0] = ($event) => showRoomDetail.value = $event),
title: unref(t)("Room Details"),
editButtonText: modifyRoom.value.visible && unref(t)("Modify"),
width: "540px",
onEdit: modifyRoom.value.func
}, createSlots({
default: withCtx(() => [
createElementVNode("div", _hoisted_10, [
createVNode(ConferenceDetail, {
conferenceInfo: props.item,
scheduleRoomDetailList: scheduleRoomDetailList.value
}, null, 8, ["conferenceInfo", "scheduleRoomDetailList"])
]),
unref(isMobile) ? (openBlock(), createElementBlock("div", _hoisted_11, [
createElementVNode("div", _hoisted_12, [
createVNode(unref(TUIButton), {
plain: "",
"custom-style": { width: "100%", padding: "10px", fontSize: "16px" },
onClick: withModifiers(joinConference, ["stop"]),
type: "primary"
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(t)("Join Room")), 1)
]),
_: 1
}),
createVNode(unref(TUIButton), {
plain: "",
"custom-style": { width: "100%", padding: "10px", fontSize: "16px" },
onClick: withModifiers(toggleInvitePanelShow, ["stop"]),
type: "primary"
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(t)("Invited members")), 1)
]),
_: 1
}),
cancelRoom.value.visible ? (openBlock(), createBlock(unref(TUIButton), {
key: 0,
color: "red",
plain: "",
"custom-style": { width: "100%", padding: "10px", fontSize: "16px" },
onClick: withModifiers(cancelRoom.value.func, ["stop"]),
type: "primary"
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(t)("cancel room")), 1)
]),
_: 1
}, 8, ["onClick"])) : createCommentVNode("", true)
]),
invitePanelShow.value ? (openBlock(), createElementBlock("div", {
key: 0,
class: "mask",
onClick: withModifiers(toggleInvitePanelShow, ["stop"])
})) : createCommentVNode("", true),
invitePanelShow.value ? (openBlock(), createElementBlock("div", _hoisted_13, [
createElementVNode("div", {
class: "invite-member-close",
onClick: toggleInvitePanelShow
}, [
createVNode(unref(IconArrowDown))
]),
createElementVNode("div", _hoisted_14, toDisplayString(unref(t)("Inviting members to join")), 1),
createVNode(InvitePanel, { scheduleInviteList: scheduleInviteList.value }, null, 8, ["scheduleInviteList"])
])) : createCommentVNode("", true)
])) : createCommentVNode("", true)
]),
_: 2
}, [
!unref(isMobile) ? {
name: "footer",
fn: withCtx(() => [
_ctx.item.status === unref(TUIConferenceStatus).kConferenceStatusNone ? (openBlock(), createBlock(unref(TUIButton), {
key: 0,
disabled: "",
type: "primary",
style: { "min-width": "88px" }
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(t)("The room is closed")), 1)
]),
_: 1
})) : (openBlock(), createElementBlock("span", _hoisted_15, [
createVNode(unref(TUIButton), {
onClick: joinConference,
type: "primary",
style: { "min-width": "88px" }
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(t)("Enter Now")), 1)
]),
_: 1
}),
createVNode(unref(TUIButton), {
onClick: toggleInviteRoom,
style: { "min-width": "88px" }
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(t)("Invited members")), 1)
]),
_: 1
})
]))
]),
key: "0"
} : void 0
]), 1032, ["visible", "title", "editButtonText", "onEdit"]),
createVNode(unref(ScheduleConferencePanel), {
visible: modifyDialogVisible.value,
"conference-info": props.item,
onInput: _cache[1] || (_cache[1] = ($event) => modifyDialogVisible.value = $event)
}, null, 8, ["visible", "conference-info"]),
createVNode(unref(Dialog), {
modelValue: showRoomCancel.value,
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => showRoomCancel.value = $event),
title: unref(t)("Cancellation of scheduled rooms"),
modal: true,
"show-close": true,
"close-on-click-modal": true,
width: "480px",
"append-to-body": true,
"title-icon": unref(IconWarning),
cancelButton: unref(t)("No cancellation"),
confirmButton: unref(t)("cancel room"),
onConfirm: handleCancelSchedule,
onCancel: _cache[4] || (_cache[4] = ($event) => showRoomCancel.value = false)
}, {
footer: withCtx(() => [
createElementVNode("span", null, [
createVNode(unref(TUIButton), {
onClick: handleCancelSchedule,
type: "primary",
style: { "min-width": "88px" }
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(t)("cancel room")), 1)
]),
_: 1
}),
createVNode(unref(TUIButton), {
onClick: _cache[2] || (_cache[2] = ($event) => showRoomCancel.value = false),
style: { "min-width": "88px" }
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(t)("No cancellation")), 1)
]),
_: 1
})
])
]),
default: withCtx(() => [
createElementVNode("span", null, toDisplayString(unref(t)("Other members will not be able to join after cancellation")), 1)
]),
_: 1
}, 8, ["modelValue", "title", "title-icon", "cancelButton", "confirmButton"]),
createVNode(unref(Dialog), {
modelValue: showRoomInvite.value,
"onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => showRoomInvite.value = $event),
title: unref(t)("sb invites you to join the conference", {
name: unref(userName) || unref(userId)
}),
modal: true,
"show-close": true,
"close-on-click-modal": true,
width: "540px",
"append-to-body": true,
"title-icon": unref(IconSuccess)
}, {
footer: withCtx(() => [
createElementVNode("span", null, [
createVNode(unref(TUIButton), {
onClick: _cache[5] || (_cache[5] = ($event) => copyRoomIdAndRoomLink()),
type: "primary"
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(unref(t)("Copy the conference number and link")), 1)
]),
_: 1
})
])
]),
default: withCtx(() => [
createVNode(InvitePanel, { scheduleInviteList: scheduleInviteList.value }, null, 8, ["scheduleInviteList"])
]),
_: 1
}, 8, ["modelValue", "title", "title-icon"])
]);
};
}
});
export {
_sfc_main as default
};