视频会议保存
This commit is contained in:
@@ -45,6 +45,54 @@
|
||||
<text class="label">{{ videoEnabled ? '停止视频' : '开启视频' }}</text>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="btn"
|
||||
:class="{ active: screenSharing, loading: screenLoading }"
|
||||
:disabled="screenLoading || screenDisabled"
|
||||
:title="screenDisabledReason || ''"
|
||||
@click="emitIf('screen-toggle')"
|
||||
>
|
||||
<view class="icon">
|
||||
<svg v-if="screenSharing" viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- 共享中:实心显示器 + 停止图示 -->
|
||||
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
|
||||
<line x1="8" y1="21" x2="16" y2="21"></line>
|
||||
<line x1="12" y1="17" x2="12" y2="21"></line>
|
||||
<line x1="6" y1="7" x2="18" y2="13"></line>
|
||||
<line x1="18" y1="7" x2="6" y2="13"></line>
|
||||
</svg>
|
||||
<svg v-else viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- 未共享:空显示器 + 上箭头 -->
|
||||
<rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
|
||||
<line x1="8" y1="21" x2="16" y2="21"></line>
|
||||
<line x1="12" y1="17" x2="12" y2="21"></line>
|
||||
<polyline points="9 10 12 7 15 10"></polyline>
|
||||
<line x1="12" y1="7" x2="12" y2="14"></line>
|
||||
</svg>
|
||||
</view>
|
||||
<text class="label">{{ screenSharing ? '停止共享' : '共享屏幕' }}</text>
|
||||
</button>
|
||||
|
||||
<!-- 录制按钮(Phase B):仅主持人可见;recording=true 时红色脉动;上传中禁用 -->
|
||||
<button
|
||||
v-if="showRecording"
|
||||
class="btn btn-recording"
|
||||
:class="{ active: recording, 'is-recording': recording, loading: recordingLoading }"
|
||||
:disabled="recordingLoading"
|
||||
@click="emitIf('recording-toggle')"
|
||||
>
|
||||
<view class="icon">
|
||||
<svg v-if="recording" viewBox="0 0 24 24" width="22" height="22" fill="currentColor" stroke="none">
|
||||
<circle cx="12" cy="12" r="6"></circle>
|
||||
</svg>
|
||||
<svg v-else viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="7"></circle>
|
||||
<circle cx="12" cy="12" r="3"></circle>
|
||||
</svg>
|
||||
</view>
|
||||
<text class="label">{{ recording ? '停止录制' : '开始录制' }}</text>
|
||||
</button>
|
||||
|
||||
<button class="btn" @click="emitIf('invite')">
|
||||
<view class="icon">
|
||||
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
@@ -102,15 +150,31 @@ const props = defineProps({
|
||||
unreadChatCount: { type: Number, default: 0 },
|
||||
allowChat: { type: Boolean, default: true },
|
||||
/** Task 15 原创特色 4:全员静音氛围色 */
|
||||
allMuted: { type: Boolean, default: false }
|
||||
allMuted: { type: Boolean, default: false },
|
||||
/** Phase 3 屏幕共享:当前用户是否在共享屏幕(决定按钮文案/高亮) */
|
||||
screenSharing: { type: Boolean, default: false },
|
||||
/** 屏幕共享操作中(getDisplayMedia / produce / closeProducer 同步等待) */
|
||||
screenLoading: { type: Boolean, default: false },
|
||||
/** 是否禁用屏幕共享按钮(有他人在共享 / 平台不支持等场景) */
|
||||
screenDisabled: { type: Boolean, default: false },
|
||||
/** 屏幕共享按钮禁用原因(hover 提示文案) */
|
||||
screenDisabledReason: { type: String, default: '' },
|
||||
/** Phase B 录制:是否显示录制按钮(仅 host 显示) */
|
||||
showRecording: { type: Boolean, default: false },
|
||||
/** Phase B 录制:当前是否在录制中 */
|
||||
recording: { type: Boolean, default: false },
|
||||
/** Phase B 录制:REST 调用 / 上传中 loading 态,禁用按钮 */
|
||||
recordingLoading: { type: Boolean, default: false }
|
||||
})
|
||||
|
||||
const emit = defineEmits(['mic-toggle', 'cam-toggle', 'invite', 'members', 'chat', 'leave'])
|
||||
const emit = defineEmits(['mic-toggle', 'cam-toggle', 'screen-toggle', 'recording-toggle', 'invite', 'members', 'chat', 'leave'])
|
||||
|
||||
/** 统一过滤 loading 态,避免重复点击 */
|
||||
const emitIf = (name) => {
|
||||
if (name === 'mic-toggle' && props.audioLoading) return
|
||||
if (name === 'cam-toggle' && props.videoLoading) return
|
||||
if (name === 'screen-toggle' && (props.screenLoading || props.screenDisabled)) return
|
||||
if (name === 'recording-toggle' && props.recordingLoading) return
|
||||
emit(name)
|
||||
}
|
||||
</script>
|
||||
@@ -191,6 +255,16 @@ const emitIf = (name) => {
|
||||
.btn-leave .icon { background: #EF4444; }
|
||||
.btn-leave:hover .icon { background: #DC2626; }
|
||||
|
||||
/* Phase B 录制按钮:录制中红色脉动 */
|
||||
.btn-recording.is-recording .icon {
|
||||
background: #EF4444;
|
||||
animation: recording-pulse 1.6s ease-in-out infinite;
|
||||
}
|
||||
@keyframes recording-pulse {
|
||||
0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.55); }
|
||||
50% { box-shadow: 0 0 0 12rpx rgba(239, 68, 68, 0); }
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: -6rpx;
|
||||
|
||||
Reference in New Issue
Block a user