@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,
172 lines (171 loc) • 6.68 kB
JavaScript
;
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const Vue = require("vue");
const StreamRegionPC = require("../StreamRegion/StreamRegionPC.vue.js");
const environment = require("../../../../utils/environment.js");
const domOperation = require("../../../../utils/domOperation.js");
const utils = require("../../../../utils/utils.js");
const _sfc_main = /* @__PURE__ */ Vue.defineComponent({
__name: "index",
props: {
streamInfoList: {},
column: {},
row: {},
fillMode: {},
aspectRatio: {},
streamPlayQuality: {},
streamPlayMode: {}
},
emits: ["stream-view-dblclick"],
setup(__props, { emit: __emit }) {
const emits = __emit;
const singleStreamMargin = environment.isPC ? 8 : 4;
const props = __props;
const streamListContainerRef = Vue.ref();
const streamListRef = Vue.ref();
const isEqualPointsLayout = Vue.computed(
() => props.column !== Infinity && props.row !== Infinity
);
const isHorizontalInfinityLayout = Vue.computed(() => props.column === Infinity);
const isVerticalInfinityLayout = Vue.computed(() => props.row === Infinity);
Vue.watch(
() => [props.column, props.row],
async () => {
await Vue.nextTick();
handleLayout();
},
{ immediate: true }
);
const validStreamInfoList = Vue.computed(() => {
var _a;
return (_a = props.streamInfoList) == null ? void 0 : _a.filter(
(item) => item && item.userId && !utils.isUndefined(item.streamType)
);
});
function handleLayout() {
if (isHorizontalInfinityLayout.value) {
handleHorizontalInfinityLayout();
return;
}
if (isVerticalInfinityLayout.value) {
handleVerticalInfinityLayout();
return;
}
if (isEqualPointsLayout.value) {
handleEqualPointsLayout();
return;
}
}
const streamListStyle = Vue.ref({
width: "0",
height: "0"
});
const streamStyle = Vue.ref({
width: "0",
height: "0",
"--stream-margin": `${singleStreamMargin / 2}px`
});
const widthRatio = Vue.computed(() => {
var _a, _b;
if (!props.aspectRatio || ((_a = props.aspectRatio) == null ? void 0 : _a.indexOf(":")) < 0) {
return 0;
}
return Number((_b = props.aspectRatio) == null ? void 0 : _b.split(":")[0]);
});
const heightRatio = Vue.computed(() => {
if (!props.aspectRatio || props.aspectRatio.indexOf(":") < 0) {
return 0;
}
return Number(props.aspectRatio.split(":")[1]);
});
async function handleEqualPointsLayout() {
if (!props.streamInfoList || !streamListContainerRef.value) {
return;
}
const containerRect = streamListContainerRef.value.getBoundingClientRect();
const containerWidth = Math.floor(containerRect.width);
const containerHeight = Math.floor(containerRect.height);
const contentWidth = (containerWidth - props.column * singleStreamMargin) / props.column;
const contentHeight = (containerHeight - props.row * singleStreamMargin) / props.row;
let width = contentWidth;
let height = contentHeight;
if (widthRatio.value && heightRatio.value) {
const scaleWidth = contentWidth / widthRatio.value;
const scaleHeight = contentHeight / heightRatio.value;
if (scaleWidth > scaleHeight) {
width = contentHeight / heightRatio.value * widthRatio.value;
height = contentHeight;
}
if (scaleWidth <= scaleHeight) {
width = contentWidth;
height = contentWidth / widthRatio.value * heightRatio.value;
}
}
streamStyle.value.width = `${width}px`;
streamStyle.value.height = `${height}px`;
streamListStyle.value.width = `${props.column * (width + singleStreamMargin)}px`;
streamListStyle.value.height = `${props.row * (height + singleStreamMargin)}px`;
}
function handleHorizontalInfinityLayout() {
streamListStyle.value = {};
const contentHeight = domOperation.getContentSize(streamListContainerRef.value).height;
const contentWidth = contentHeight * widthRatio.value / heightRatio.value;
streamStyle.value.width = `${contentWidth}px`;
streamStyle.value.height = `${contentHeight}px`;
}
function handleVerticalInfinityLayout() {
streamListStyle.value = {};
const contentWidth = domOperation.getContentSize(streamListContainerRef.value).width;
const contentHeight = contentWidth * heightRatio.value / widthRatio.value;
streamStyle.value.width = `${contentWidth}px`;
streamStyle.value.height = `${contentHeight}px`;
}
function handleStreamDblClick(streamInfo) {
emits("stream-view-dblclick", streamInfo);
}
const resizeObserver = new ResizeObserver(() => {
handleLayout();
});
Vue.onMounted(() => {
resizeObserver.observe(streamListContainerRef.value);
});
Vue.onBeforeUnmount(() => {
resizeObserver.unobserve(streamListContainerRef.value);
});
function handleWheel(event) {
streamListContainerRef.value.scrollLeft += event.deltaY;
}
return (_ctx, _cache) => {
return Vue.openBlock(), Vue.createElementBlock("div", {
ref_key: "streamListContainerRef",
ref: streamListContainerRef,
class: Vue.normalizeClass({
"horizontal-infinity-layout": isHorizontalInfinityLayout.value,
"vertical-infinity-layout": isVerticalInfinityLayout.value,
"equal-points-layout": isEqualPointsLayout.value
})
}, [
Vue.createElementVNode("div", {
class: "stream-list",
ref_key: "streamListRef",
ref: streamListRef,
style: Vue.normalizeStyle(streamListStyle.value),
onWheel: handleWheel
}, [
(Vue.openBlock(true), Vue.createElementBlock(Vue.Fragment, null, Vue.renderList(validStreamInfoList.value, (streamInfo) => {
return Vue.openBlock(), Vue.createBlock(Vue.unref(StreamRegionPC.default), {
class: "stream-list-item",
key: `${streamInfo.userId}_${streamInfo.streamType}`,
streamInfo,
style: Vue.normalizeStyle(streamStyle.value),
streamPlayMode: _ctx.streamPlayMode,
streamPlayQuality: _ctx.streamPlayQuality,
onStreamViewDblclick: handleStreamDblClick
}, null, 8, ["streamInfo", "style", "streamPlayMode", "streamPlayQuality"]);
}), 128))
], 36)
], 2);
};
}
});
exports.default = _sfc_main;