chat-pc/src/components/search/searchByCondition.vue

994 lines
32 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="outer-layer search-by-condition-page">
<n-infinite-scroll style="height: 455px;" :distance="10">
<div class="root">
<div v-if="state.condition === 'dateTimePicker'" class="search-by-date">
<n-date-picker
:panel="true"
type="datetime"
:clearable="true"
:first-day-of-week="6"
:is-date-disabled="dateDisabled"
:actions="['clear', 'confirm']"
/>
<!-- <tm-time-picker
:show="state.showMonthPicker"
:showDetail="{
year: true,
month: true,
day: false,
hour: false,
minute: false,
second: false,
am_pm: false
}"
:showSuffix="{
year: '',
month: ''
}"
:defaultValue="state.nowDate"
format="YYYY年MM月"
start=""
:end="state.maxDate"
@confirm="confirmSelectedMonth"
:round="0"
:title="'请选择聊天日期'"
>
<div class="search-date-picker">
<span class="text-[14px] font-regular">
{{ state.selectedMonth }}
</span>
<img src="@/static/image/search/down-pointer.png" />
</div>
</tm-time-picker> -->
<!-- <tm-calendar-view
:show="true"
:hideTool="true"
:hideButton="true"
:dateStyle="state.dateStyle"
:defaultValue="state.selectedDateArray"
v-model="state.selectedDateArray"
:disabledDate="state.disabledDateArray"
@click="selectDate"
model="day"
:end="state.maxDate"
@getDArray="getDArray"
:showDefault="false"
></tm-calendar-view> -->
</div>
<div
class="search-by-condition-input-list"
v-if="
state.condition === 'imgAndVideo' ||
state.condition === 'file' ||
state.condition === 'link' ||
state.condition === 'member'
"
:style="{
padding: state.condition === 'imgAndVideo' ? '20px 38px' : ''
}"
>
<!-- <div
class="search-by-condition-input"
v-if="state.condition === 'file' || state.condition === 'link'"
>
<customInput
:searchText="state.searchText"
:first_talk_record_infos="state.first_talk_record_infos"
@inputSearchText="inputSearchText"
></customInput>
<span
@click="cancelSearch"
class="search-by-condition-input-text text-[16px] font-medium"
>
取消
</span>
</div> -->
<div class="search-by-condition-list">
<div class="condition-dimensionality">
<div
class="condition-dimensionality-each"
v-for="(conditionItem, conditionIndex) in state.searchResultList"
:key="conditionIndex"
>
<div
class="condition-dimensionality-each-month"
v-if="state.condition === 'imgAndVideo'"
>
<span class="text-[14px] font-regular">
{{ conditionItem.dateMonth }}
</span>
</div>
<div
class="condition-each-resultList"
:class="[
state.condition === 'imgAndVideo' ? 'condition-type-imgAndVideo-result' : ''
]"
>
<div
class="condition-each-resultList-each"
v-for="(item, index) in conditionItem.monthResultList"
:key="index"
:style="{
border:
state.condition === 'imgAndVideo' || state.condition === 'member'
? '0'
: '',
padding: state.condition === 'imgAndVideo' ? '' : ''
}"
>
<div class="condition-result-member" v-if="state.condition === 'member'">
<searchItem
@click="toDialogueByMember(item)"
:searchResultKey="'search_by_member_condition'"
:searchItem="item"
:searchText="state.searchText"
:searchRecordDetail="true"
></searchItem>
</div>
<div
class="condition-result-imgAndVideo"
v-if="state.condition === 'imgAndVideo'"
>
<div
class="condition-result-imgAndVideo-area condition-result-imgAndVideo-area-imgText"
v-if="item?.extra?.items?.length > 0"
>
<n-scrollbar style="height: 131px;">
<div
class="condition-result-imgAndVideo-each"
v-for="(imgItem, imgIndex) in item?.extra?.items"
:key="imgIndex"
>
<n-image
:src="imgItem?.content"
v-if="imgItem?.type == 3"
:lazy="true"
:preview-src="imgItem?.content"
:width="131"
:height="131"
object-fit="cover"
></n-image>
</div>
</n-scrollbar>
</div>
<div class="condition-result-imgAndVideo-area" v-if="item?.extra?.url">
<template v-if="item?.msg_type === 3">
<n-image
:src="item?.extra?.url"
:lazy="true"
:preview-src="item?.extra?.url"
:width="131"
:height="131"
object-fit="cover"
></n-image>
</template>
<template v-else-if="item?.msg_type === 5">
<div class="video-preview" @click="onPlay(item?.extra?.url)">
<video :src="item?.extra?.url" :controls="false"></video>
<!-- <n-image
:src="
item?.extra?.url
? item?.extra?.url + '#t=0.001'
: item?.extra?.cover
"
:width="131"
:height="131"
object-fit="cover"
></n-image> -->
<div class="btn-video">
<!-- <img :src="playCircle" /> -->
<n-icon :component="Play" size="40" />
</div>
</div>
</template>
</div>
</div>
<!-- <div
class="condition-each-result-main"
v-if="state.condition === 'file' || state.condition === 'link'"
>
<searchItem :searchItem="item" :conditionType="state.msg_type"></searchItem>
<span class="text-[12px] font-medium condition-each-result-main-date">
{{ item.dateTime }}
</span>
</div> -->
<div
class="condition-each-result-attachments"
@click="previewPDF(item)"
v-if="state.condition === 'file' || state.condition === 'link'"
>
<div class="attachment-avatar">
<img :src="item?.extra?.file_avatar" v-if="state.condition === 'file'" />
<!-- <img
src="@/static/image/search/result-link-icon.png"
v-if="state.condition === 'link'"
/> -->
</div>
<div class="attachment-info">
<div class="attachment-info-title">
<span class="text-[14px] font-regular" v-if="state.condition === 'file'">
{{ item?.extra?.name }}
</span>
<span class="text-[14px] font-regular" v-if="state.condition === 'link'">
分享链接
</span>
<span
class="text-[14px] font-regular"
v-if="state.condition === 'file'"
style="color: #999999;"
>
{{ item.dateTime }}
</span>
</div>
<div
class="attachment-sub-info"
:style="{
margin: state.condition === 'file' ? '10px 0 0' : ''
}"
>
<!-- <span class="text-[12px] font-regular" v-if="state.condition === 'file'">
{{ item?.extra?.typeText }}
</span>
<span class="text-[12px] font-regular" v-if="state.condition === 'link'">
{{ item?.extra?.content }}
</span> -->
<span class="text-[12px] font-regular" v-if="state.condition === 'file'">
{{ item?.nickname }}
</span>
<span class="text-[12px] font-regular" v-if="state.condition === 'file'">
{{ item?.extra?.fileSize }}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <ZPaging
ref="zPaging"
:show-scrollbar="false"
@query="queryAllSearch"
:refresher-enabled="false"
:auto="false"
:loading-more-default-as-loading="true"
:inside-more="true"
v-model="state.flatList"
>
<template #top v-if="state.showPageTitle">
<customNavbar :title="state.pageTitle"></customNavbar>
</template>
</ZPaging> -->
<teleport to="body">
<div v-show="open" class="video-container">
<video
:src="currentVideoUrl"
controls
@fullscreenchange="fullscreenchange"
:id="currentVideoUrl"
playsinline
webkit-playsinline
x5-playsinline
class="fullscreen-video"
></video>
</div>
</teleport>
</div>
</n-infinite-scroll>
</div>
</template>
<script setup>
// import playCircle from '@/assets/image/icon/play-circle.png'
// import customInput from '@/components/custom-input/custom-input.vue'
// import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
// import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
// const zPaging = ref()
// useZPaging(zPaging)
import { Play } from '@icon-park/vue-next'
import fileType_PPT from '@/assets/image/ppt-text.png'
import fileType_EXCEL from '@/assets/image/excel-text.png'
import fileType_WORD from '@/assets/image/word-text.png'
import fileType_PDF from '@/assets/image/pdf-text.png'
import fileType_Files from '@/assets/image/file-text.png'
import { useDialogueStore } from '@/store'
import { onMounted, reactive, computed, ref, nextTick, watch } from 'vue'
import searchItem from './searchItem.vue'
import { ServeFindTalkRecords } from '@/api/chat.js'
import { ServeTalkDate, ServeGetSessionId } from '@/api/search.js'
import { parseTime } from '@/utils/datetime'
import { fileFormatSize, fileSuffix } from '@/utils/strings'
import { NImage, NInfiniteScroll, NScrollbar, NIcon, NDatePicker } from 'naive-ui'
const dialogueStore = useDialogueStore()
// 当前对话参数
const dialogueParams = reactive({
talk_type: computed(() => dialogueStore.talk.talk_type),
receiver_id: computed(() => dialogueStore.talk.receiver_id)
})
let nowDay = new Date().setHours(0, 0, 0, 0)
const props = defineProps({
conditionType: {
//搜索条件
type: String,
default: ''
}
})
const state = reactive({
pageTitle: '', //页面标题
dateStyle: [], //日期样式
nowDate: new Date(nowDay), //当前时间
maxDate: new Date(nowDay), //可选择最大时间
selectedDateArray: Array(new Date(nowDay)), //选择的月份数组
showMonthPicker: false, //是否显示月份选择
selectedMonth: new Date(nowDay), //当前选择的月份
disabledDateArray: [], //被禁用的日期数组
dArray: [], //日历日期数组
showPageTitle: false, //是否显示页面标题
searchText: '', //搜索内容
first_talk_record_infos: Object,
searchResultList: [], //搜索结果列表
cursor: 0, //上次查询的游标
msg_type: 0, //查询的消息类型
group_member_id: 0, //群成员id
flatList: [] // 用于存储扁平化的数据
})
const videoContext = ref()
const open = ref(false)
const currentVideoUrl = ref('')
const fullscreenchange = (e) => {
if (!e.detail.fullScreen) {
videoContext.value.stop()
videoContext.value.seek(0)
open.value = false
}
}
async function onPlay(url) {
currentVideoUrl.value = url
open.value = true
// 等待 DOM 更新
await nextTick()
// 创建新的视频上下文
videoContext.value = uni.createVideoContext(url, getCurrentInstance())
setTimeout(() => {
// 先请求全屏
videoContext.value.requestFullScreen({ direction: 2 })
// 延迟一下再播放,确保全屏已经完成
setTimeout(() => {
videoContext.value.play()
}, 100)
}, 200)
}
onMounted(() => {
state.selectedMonth = parseTime(state.selectedMonth, '{y}年{m}月')
state.dateStyle = [
{
date: state.nowDate, //日期
text: false, //浅色背景。
color: '#46299D', //主题色.
extra: '今天' //额外的内容,在日期下方显示的文本。
}
]
})
//查看存在聊天记录的天数
const ServeQueryTalkDate = (month) => {
let params = {
month: month,
talk_type: dialogueParams.talk_type, //1私聊2群聊
receiver_id: dialogueParams.receiver_id //目标人id
}
const resp = ServeTalkDate(params)
console.log(resp)
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
if (data && data.length > 0) {
const formattedData = data.map(
(item) => item.substring(0, 4) + '/' + item.substring(4, 6) + '/' + item.substring(6, 8)
)
let disabledDateArray = state.dArray.filter((dIt) => !formattedData.includes(dIt))
disabledDateArray = disabledDateArray.map((item) => item.replace(/\//g, '/'))
console.log(disabledDateArray)
state.disabledDateArray = disabledDateArray
} else {
state.disabledDateArray = state.dArray
}
} else {
}
})
resp.catch(() => {})
}
//禁用的日期
const dateDisabled = (e) => {
const date = new Date(e)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const formattedDate = `${year}/${month}/${day}`
return state.disabledDateArray.includes(formattedDate)
}
//点击选择日期
const selectDate = async (e) => {
if (e == parseTime(state.nowDate, '{y}/{m}/{d}')) {
console.log('==今日')
state.dateStyle = [
{
date: state.nowDate, //日期
text: false, //浅色背景。
color: '#46299D', //主题色.
extra: '今天' //额外的内容,在日期下方显示的文本。
}
]
} else {
state.dateStyle = [
{
date: state.nowDate, //日期
text: false, //浅色背景。
color: '', //主题色.
extra: '今天' //额外的内容,在日期下方显示的文本。
},
{
date: new Date(e), //日期
text: false, //浅色背景。
color: '#46299D' //主题色.
}
]
}
const sessionId = await getSessionId(dialogueParams.talk_type, dialogueParams.receiver_id)
uni.navigateTo({
url:
'/pages/dialog/index?sessionId=' +
sessionId +
'&keepDialogInfo=1' +
'&recordDate=' +
parseTime(e, '{y}-{m}-{d}')
})
}
//获取会话Id
const getSessionId = (talk_type, receiver_id) => {
return new Promise((resolve, reject) => {
let params = {
talkType: talk_type,
receiverId: receiver_id
}
const resp = ServeGetSessionId(params)
console.log(resp)
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
resolve(data?.sessionId)
} else {
}
})
resp.catch(() => {})
})
}
//点击确认选择月份
const confirmSelectedMonth = (e) => {
console.log(e)
state.selectedMonth = parseTime(e, '{y}年{m}月')
// console.log()
let newDate = new Date(e)
newDate.setHours(0, 0, 0, 0)
newDate.setDate(1)
state.selectedDateArray = Array(new Date(newDate))
state.dateStyle = [
{
date: state.nowDate, //日期
text: false, //浅色背景。
color: '', //主题色.
extra: '今天' //额外的内容,在日期下方显示的文本。
}
]
ServeQueryTalkDate(parseTime(e, '{y}{m}'))
}
//获取日历日期数组
const getDArray = (selectedMonth) => {
const [year, month] = selectedMonth.split('-').map(Number)
const daysInMonth = new Date(year, month, 0).getDate()
const dArray = Array.from({ length: daysInMonth }, (_, i) => {
const day = i + 1
return `${year}/${String(month).padStart(2, '0')}/${String(day).padStart(2, '0')}`
})
state.dArray = dArray
}
//输入搜索内容
const inputSearchText = (e) => {
state.searchText = e
state.cursor = 0
queryAllSearch()
}
//点击取消搜索
const cancelSearch = () => {
const pages = getCurrentPages()
if (pages.length > 1) {
uni.navigateBack({
delta: 1
})
} else {
uni.reLaunch({
url: '/pages/index/index'
})
}
}
//查询数据
const queryAllSearch = () => {
let params = {
talk_type: dialogueParams.talk_type, //1私聊2群聊
receiver_id: dialogueParams.receiver_id, //目标用户id或群聊id
msg_type: state.msg_type, //消息类型0:全部;2:代码;3:图片;4:音频;5:视频;6:文件;7:位置;9:会话;11群投票;12图文混合
cursor: state.cursor, //上次查询的游标
limit: 10, //数据行数
no_limit: '', //1不限制
direction: 'up', //down向下查最新up向上查老数据
start_time: '',
end_time: '',
group_member_user_id: state.group_member_id, //群成员id当查询群历史消息的时候需要指定群成员的时候送
file_name: state.msg_type === 6 ? state.searchText : ''
}
console.log(params)
const resp = ServeFindTalkRecords(params)
console.log(resp)
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
// 当cursor为0时清空searchResultList
let dateList = state.cursor === 0 ? [] : state.searchResultList
let noMore = false
if (data?.items?.length > 0) {
data.items.forEach((item) => {
item.dateTime = parseTime(item?.created_at, '{m}/{d}')
if (item?.extra) {
item.extra.fileSize = fileFormatSize(item?.extra?.size)
item.extra.typeText = item?.extra?.name ? fileSuffix(item?.extra?.name) : ''
item.extra.file_avatar = fileTypeAvatar(item?.extra?.typeText)
console.log(item.extra.type)
}
let year = new Date(item.created_at).getFullYear()
let month = new Date(item.created_at).getMonth() + 1
let dateMonth =
year == state.nowDate.getFullYear() && month == state.nowDate.getMonth() + 1
? '这个月'
: year + '年' + month + '月'
if (dateList.length > 0) {
let hasAdd = false
dateList.forEach((dateItem) => {
if (dateItem.dateMonth === dateMonth) {
dateItem.monthResultList.push(item)
hasAdd = true
}
})
if (!hasAdd) {
console.log(dateList)
dateList.push({
dateMonth: dateMonth,
monthResultList: [item]
})
}
} else {
dateList.push({
dateMonth: dateMonth,
monthResultList: [item]
})
}
})
} else {
noMore = true
}
// 保存分组数据用于显示
state.searchResultList = dateList
// 将分组数据扁平化用于z-paging分页
state.flatList = dateList.reduce((acc, group) => {
return acc.concat(group.monthResultList)
}, [])
if (state.cursor === 0) {
// zPaging.value?.complete(state.flatList)
} else {
// zPaging.value?.completeByNoMore(state.flatList, noMore)
}
state.cursor = data?.cursor
} else {
if (state.cursor === 0) {
state.searchResultList = []
state.flatList = []
}
// zPaging.value?.complete([])
}
})
resp.catch(() => {
if (state.cursor === 0) {
state.searchResultList = []
state.flatList = []
}
// zPaging.value?.complete([])
})
}
//文件类型图标
const fileTypeAvatar = (fileType) => {
let file_type_avatar = fileType_Files
if (fileType) {
if (fileType === 'ppt' || fileType === 'pptx') {
file_type_avatar = fileType_PPT
} else if (fileType === 'pdf') {
file_type_avatar = fileType_PDF
} else if (fileType === 'doc' || fileType === 'docx') {
file_type_avatar = fileType_WORD
} else if (fileType === 'xls' || fileType === 'xlsx') {
file_type_avatar = fileType_EXCEL
} else {
file_type_avatar = fileType_Files
}
}
return file_type_avatar
}
const previewPDF = (item) => {
console.log(item)
if (typeof plus !== 'undefined') {
downloadAndOpenFile(item)
} else {
document.addEventListener('plusready', () => {
downloadAndOpenFile(item)
})
}
}
const downloadAndOpenFile = (item) => {
uni.showLoading({ title: '加载中...', mask: true })
const downloadUrl = item?.extra?.path
const options = {
filename: '_doc/downloads/' // 保存路径
}
const dtask = plus.downloader.createDownload(downloadUrl, options, function (d, status) {
if (status === 200) {
uni.hideLoading()
const filePath = d.filename
plus.runtime.openFile(
filePath,
{},
function () {},
function (error) {}
)
} else {
uni.hideLoading()
}
})
dtask.start()
}
//跳转到对应的记录位置
const toDialogueByMember = async (msgInfo) => {
const sessionId = await getSessionId(dialogueParams.talk_type, dialogueParams.receiver_id)
uni.navigateTo({
url:
'/pages/dialog/index?sessionId=' +
sessionId +
'&keepDialogInfo=1' +
'&msgInfo=' +
encodeURIComponent(JSON.stringify(msgInfo))
})
}
watch(
() => props?.conditionType,
(newVal, oldVal) => {
console.log(newVal, oldVal)
state.condition = newVal
if (newVal) {
if (newVal === 'member') {
state.showPageTitle = true
state.pageTitle = '按群成员查找'
// state.group_member_id = options.groupMemberId
queryAllSearch()
} else if (newVal === 'dateTimePicker') {
state.showPageTitle = true
state.pageTitle = '按日期查找'
ServeQueryTalkDate(parseTime(state.nowDate, '{y}{m}'))
getDArray(parseTime(state.nowDate, '{y}-{m}'))
} else if (newVal === 'imgAndVideo') {
state.showPageTitle = true
state.pageTitle = '图片与视频'
state.msg_type = '3,5'
queryAllSearch()
} else if (newVal === 'file') {
console.log(dialogueParams)
let first_talk_record_infos = {
receiver_name: '文件'
}
state.first_talk_record_infos = Object.assign(
{},
state.first_talk_record_infos,
first_talk_record_infos
)
state.msg_type = 6
queryAllSearch()
} else if (newVal === 'link') {
console.log(dialogueParams)
let first_talk_record_infos = {
receiver_name: '链接'
}
state.first_talk_record_infos = Object.assign(
{},
state.first_talk_record_infos,
first_talk_record_infos
)
state.msg_type = 14
queryAllSearch()
}
}
},
{
immediate: true,
deep: true
}
)
</script>
<style scoped lang="scss">
.search-by-date {
:deep(.n-date-panel-header) {
display: none;
}
.search-date-picker {
padding: 10px 16px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
span {
line-height: 20px;
color: #999999;
}
img {
width: 9px;
height: 6px;
margin: 0 0 0 13px;
}
}
}
body:deep(.text-overflow-1) {
color: #666666 !important;
line-height: 22px !important;
font-size: 16px !important;
font-weight: bold !important;
}
body:deep(.tmicon-times-circle-fill) {
width: 19px;
height: 19px;
}
body:deep(.round-3) {
background: linear-gradient(to right, #674bbc, #46299d);
}
.search-by-condition-input-list {
// padding: 10px 24px 0 21px;
padding: 20px 40px;
.search-by-condition-input {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.search-by-condition-input-text {
flex-shrink: 0;
margin: 0 0 0 10px;
color: #46299d;
}
}
.search-by-condition-list {
.condition-dimensionality {
.condition-dimensionality-each {
.condition-dimensionality-each-month {
padding: 0 0 18px;
span {
line-height: 20px;
color: #999999;
}
}
.condition-each-resultList {
.condition-each-resultList-each {
border-bottom: 1px solid #f8f8f8;
.condition-each-result-main {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.condition-each-result-main-date {
line-height: 17px;
color: #999999;
}
}
.condition-each-result-attachments {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 14px 0;
// background-color: #f3f3f3;
border-radius: 4px;
.attachment-avatar {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
flex-shrink: 0;
img {
width: 48px;
height: 48px;
}
}
.attachment-info {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
margin: 0 0 0 11px;
width: 100%;
.attachment-info-title {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
span {
line-height: 20px;
color: #191919;
word-break: break-all;
}
}
.attachment-sub-info {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
span {
line-height: 17px;
color: #999999;
word-break: break-all;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
}
}
.condition-type-imgAndVideo-result {
border-bottom: 0;
padding: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
flex-wrap: wrap;
gap: 12px;
.condition-each-resultList-each {
.condition-result-imgAndVideo {
::-webkit-scrollbar {
display: none;
}
:deep(.overflow) {
width: 131px !important;
height: 131px !important;
}
.condition-result-imgAndVideo-area {
:deep(.overflow) {
width: 131px !important;
height: 131px !important;
}
:deep(.round-0) {
width: 131px !important;
height: 131px !important;
}
.video-preview {
// position: relative;
// .play-icon {
// position: absolute;
// top: 50%;
// left: 50%;
// transform: translate(-50%, -50%);
// display: flex;
// align-items: center;
// justify-content: center;
// img {
// width: 40px !important;
// height: 40px !important;
// }
// }
display: inline-flex;
position: relative;
cursor: pointer;
width: 131px;
height: 131px;
video {
width: 100%;
height: 100%;
object-fit: cover;
background-color: #333; /* 添加背景色避免默认显示为灰色 */
}
.btn-video {
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
position: absolute;
cursor: pointer;
color: #fff;
}
&:hover {
.btn-video {
color: #46299d;
}
}
}
}
}
}
}
}
.condition-dimensionality-each:nth-child(1) {
.condition-each-result-attachments {
padding: 0 0 14px !important;
}
}
}
}
}
.video-container {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: #000;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.fullscreen-video {
width: 100%;
height: 100%;
object-fit: contain;
}
</style>