1782 lines
58 KiB
Vue
1782 lines
58 KiB
Vue
<template>
|
||
<div id="comments-and-replays" class="flex-grow-1 position-relative">
|
||
<!-- header : group info -->
|
||
<div class="chat-list-group-info">
|
||
<!-- start: show right list -->
|
||
<button
|
||
v-if="!sidebarListStatusGetter"
|
||
type="button"
|
||
class="btn d-flex ps-0 ps-lg-2 align-items-center"
|
||
@click.prevent="closeList()"
|
||
>
|
||
<span
|
||
:style="{
|
||
transform: `rotateY(${
|
||
!sidebarListStatusGetter ? '0deg' : '180deg'
|
||
} )`,
|
||
}"
|
||
class="tavasi tavasi-Component-71--1"
|
||
></span>
|
||
</button>
|
||
<!-- end: show right list -->
|
||
|
||
<!-- <button type="button" class="btn ps-0 ps-lg-2 d-lg-none" @click="$root.$emit('open-list', this.menubarStatus)">
|
||
<span class="tavasi tavasi-Component-71--1"></span>
|
||
</button> -->
|
||
|
||
<!-- start: selected list info -->
|
||
<button
|
||
type="button"
|
||
class="btn group-row"
|
||
:title="titleGetter + '\r\n' + listGetter?.desc"
|
||
>
|
||
<div class="group-picture-container">
|
||
<img
|
||
class="group-picture"
|
||
:src="sourceGetter"
|
||
:alt="listGetter?.title"
|
||
/>
|
||
</div>
|
||
<div class="group-content">
|
||
<div class="group-title-container">
|
||
<h4 class="group-title">
|
||
<!-- <span class="tavasi tavasi-personal"></span> -->
|
||
<svg :class="'icon icon-' + iconGetter">
|
||
<use :xlink:href="'#icon-' + iconGetter"></use>
|
||
</svg>
|
||
{{ listGetter?.title }}
|
||
</h4>
|
||
</div>
|
||
<div class="group-description-container">
|
||
<p class="group-description" v-html="listGetter?.desc ?? null"></p>
|
||
</div>
|
||
</div>
|
||
</button>
|
||
<!-- end: selected list info -->
|
||
|
||
<div v-if="!isGuest">
|
||
<div
|
||
class="group-info-actions d-flex px-3 align-items-center"
|
||
style="white-space: nowrap"
|
||
>
|
||
<div v-if="$route.name !== 'privates'">
|
||
<a
|
||
v-if="listGetter?.reference_id && isIssueGroup()"
|
||
:href="'/jahat/' + buttonName + '/' + listGetter?.reference_id"
|
||
:title="buttonTitle"
|
||
@click.prevent="goToJahat()"
|
||
class="btn btn-default issue-redirect-btn"
|
||
>
|
||
{{ buttonTitle }}
|
||
</a>
|
||
<a
|
||
v-if="listGetter?.reference_id && isAnswerGroup()"
|
||
:href="
|
||
'/jahat/answers/' +
|
||
listGetter.parent_reference +
|
||
'/' +
|
||
listGetter?.reference_id
|
||
"
|
||
:title="buttonTitle"
|
||
@click.prevent="goToJahat()"
|
||
class="btn btn-default issue-redirect-btn"
|
||
>
|
||
{{ buttonTitle }}
|
||
</a>
|
||
|
||
<multiselect
|
||
v-model="selectedLabel"
|
||
class="ms-2 hiden3"
|
||
id="labels"
|
||
track-by="entity_field_id"
|
||
placeholder="فیلتر برچسب ها"
|
||
label="lable"
|
||
:multiple="false"
|
||
:options="listGetter?.entity_labels ?? []"
|
||
:allow-empty="true"
|
||
:searchable="true"
|
||
:options-limit="300"
|
||
:limit="10"
|
||
:limit-text="limitText"
|
||
:max-height="350"
|
||
@select="filterMessagesBySection"
|
||
@remove="filterMessagesBySection(undefined)"
|
||
selectLabel=""
|
||
selectedLabel=""
|
||
deselectLabel=""
|
||
:close-on-select="true"
|
||
:clear-on-select="false"
|
||
:preserve-search="true"
|
||
>
|
||
<div slot="selection" slot-scope="{ values, search, isOpen }">
|
||
<span
|
||
class="multiselect__single"
|
||
v-if="values.length"
|
||
v-show="!isOpen"
|
||
>{{ values.length }} فیلتر</span
|
||
>
|
||
</div>
|
||
<div slot="noResult" slot-scope="{ values, search, isOpen }">
|
||
چیزی یافت نشد.
|
||
</div>
|
||
<div slot="noOptions" slot-scope="{ values, search, isOpen }">
|
||
فهرست خالی است.
|
||
</div>
|
||
<!-- <div slot="beforeList" slot-scope="{ values, search, isOpen }">
|
||
beforeList
|
||
</div>
|
||
<div slot="afterList" slot-scope="{ values, search, isOpen }">
|
||
afterList
|
||
</div> -->
|
||
<!-- <div slot="singleLabel" slot-scope="{ values, search, isOpen }">
|
||
singleLabel
|
||
</div>
|
||
-->
|
||
<!-- <div slot="singleLabel" slot-scope="props">
|
||
<span class="option__desc"
|
||
><span class="option__title">{{ props.option.title }}</span></span
|
||
></div
|
||
>
|
||
<div slot="option" slot-scope="props">
|
||
<div class="option__desc">
|
||
<span class="option__title">{{ props.option.lable }}</span>
|
||
</div>
|
||
</div> -->
|
||
</multiselect>
|
||
<div class="multiselect-container ms-2">
|
||
<span class="badge badge-primary" title="تعداد اعضاء">
|
||
{{ groupMember?.length ?? 0 }}
|
||
</span>
|
||
|
||
<multiselect
|
||
v-model="selectedMember"
|
||
id="members"
|
||
class="hiden3"
|
||
track-by="user_id"
|
||
placeholder="فیلتر کاربران"
|
||
:show-labels="false"
|
||
:options="groupMember"
|
||
:searchable="true"
|
||
:allow-empty="true"
|
||
:close-on-select="true"
|
||
:options-limit="300"
|
||
:limit="3"
|
||
:limit-text="limitText"
|
||
:max-height="350"
|
||
:customLabel="
|
||
(item) => {
|
||
return `${item.full_name}`;
|
||
}
|
||
"
|
||
@select="filterMessagesByUser"
|
||
@remove="filterMessagesByUser(undefined)"
|
||
>
|
||
</multiselect>
|
||
</div>
|
||
|
||
<!-- <button class="btn" type="button">
|
||
<span class="tavasi tavasi-Component-285--2"></span>
|
||
</button> -->
|
||
</div>
|
||
|
||
<button
|
||
v-if="$route.name != 'lobbies'"
|
||
@click.prevent="showMessageSearch()"
|
||
class="btn"
|
||
type="button"
|
||
>
|
||
<span class="tavasi tavasi-Component-198--1"></span>
|
||
</button>
|
||
|
||
<context-menu
|
||
maxHeight="15rem"
|
||
ref="context"
|
||
class="position-static group-info-context-menu"
|
||
:list="commonContextMenu"
|
||
:contextMenu="commonContextMenu"
|
||
@remove-item="fireRemoveItemEvent"
|
||
@edit-item="fireEditItemEvent"
|
||
@join-to-group="fireAddToLobbyEvent"
|
||
@copy-item="fireCopyLinkEvent"
|
||
@other="fireCopyLinkEvent"
|
||
@filter="showFilter = true"
|
||
height="auto"
|
||
></context-menu>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div
|
||
class="menu-multiselect hiden1 hiden2 hiden"
|
||
v-if="$route.name !== 'privates' && showFilter"
|
||
>
|
||
<div class="open m-2" @click="closefilter()">
|
||
<span class="tavasi tavasi-Component-294--1"></span>
|
||
</div>
|
||
|
||
<multiselect
|
||
v-model="selectedLabel"
|
||
class="ms-2 hiden3"
|
||
id="labels"
|
||
track-by="entity_field_id"
|
||
placeholder="فیلتر برچسب ها"
|
||
label="lable"
|
||
:multiple="false"
|
||
:options="listGetter?.entity_labels ?? []"
|
||
:allow-empty="true"
|
||
:searchable="true"
|
||
:options-limit="300"
|
||
:limit="10"
|
||
:limit-text="limitText"
|
||
:max-height="350"
|
||
@select="filterMessagesBySection"
|
||
@remove="filterMessagesBySection(undefined)"
|
||
selectLabel=""
|
||
selectedLabel=""
|
||
deselectLabel=""
|
||
:close-on-select="true"
|
||
:clear-on-select="false"
|
||
:preserve-search="true"
|
||
>
|
||
<div slot="selection" slot-scope="{ values, search, isOpen }">
|
||
<span
|
||
class="multiselect__single"
|
||
v-if="values.length"
|
||
v-show="!isOpen"
|
||
>{{ values.length }} فیلتر</span
|
||
>
|
||
</div>
|
||
<div slot="noResult" slot-scope="{ values, search, isOpen }">
|
||
چیزی یافت نشد.
|
||
</div>
|
||
<div slot="noOptions" slot-scope="{ values, search, isOpen }">
|
||
فهرست خالی است.
|
||
</div>
|
||
<!-- <div slot="beforeList" slot-scope="{ values, search, isOpen }">
|
||
beforeList
|
||
</div>
|
||
<div slot="afterList" slot-scope="{ values, search, isOpen }">
|
||
afterList
|
||
</div> -->
|
||
<!-- <div slot="singleLabel" slot-scope="{ values, search, isOpen }">
|
||
singleLabel
|
||
</div>
|
||
-->
|
||
<!-- <div slot="singleLabel" slot-scope="props">
|
||
<span class="option__desc"
|
||
><span class="option__title">{{ props.option.title }}</span></span
|
||
></div
|
||
>
|
||
<div slot="option" slot-scope="props">
|
||
<div class="option__desc">
|
||
<span class="option__title">{{ props.option.lable }}</span>
|
||
</div>
|
||
</div> -->
|
||
</multiselect>
|
||
<div class="multiselect-container">
|
||
<span class="badge badge-primary" title="تعداد اعضاء">
|
||
{{ groupMember?.length ?? 0 }}
|
||
</span>
|
||
<multiselect
|
||
v-model="selectedMember"
|
||
class="m-2"
|
||
id="members"
|
||
track-by="user_id"
|
||
placeholder="فیلتر کاربران"
|
||
:show-labels="false"
|
||
:options="groupMember"
|
||
:searchable="true"
|
||
:allow-empty="true"
|
||
:close-on-select="true"
|
||
:options-limit="300"
|
||
:limit="3"
|
||
:limit-text="limitText"
|
||
:max-height="350"
|
||
:customLabel="
|
||
(item) => {
|
||
return `${item.full_name}`;
|
||
}
|
||
"
|
||
@select="filterMessagesByUser"
|
||
@remove="filterMessagesByUser(undefined)"
|
||
>
|
||
<div slot="singleLabel" slot-scope="props">
|
||
<span class="option__desc"
|
||
><span class="option__title">{{
|
||
props.option.full_name
|
||
}}</span></span
|
||
>
|
||
</div>
|
||
</multiselect>
|
||
</div>
|
||
</div>
|
||
|
||
<div
|
||
class="mt-3 d-flex align-items-center px-3"
|
||
v-if="selectedLabel || selectedMember"
|
||
>
|
||
<div class="flex-grow-1 d-flex align-items-center">
|
||
<button
|
||
@click.prevent="showMobileActions = true"
|
||
class="btn selected-filter-list d-xl-none"
|
||
type="button"
|
||
>
|
||
<svg class="icon icon-filter-list">
|
||
<use xlink:href="#icon-filter-list"></use>
|
||
</svg>
|
||
<span class="mx-1">
|
||
1
|
||
<!-- {{ selectedLabel ? [selectedLabel].length : [selectedMember].length }} -->
|
||
</span>
|
||
فیلتر
|
||
</button>
|
||
|
||
<filter-list
|
||
v-if="selectedLabel"
|
||
styleClass="style-2"
|
||
keyName="lable"
|
||
:filters="[selectedLabel]"
|
||
@remove-filter="removeFromLabelFilter"
|
||
></filter-list>
|
||
|
||
<filter-list
|
||
v-if="selectedMember"
|
||
styleClass="style-2"
|
||
keyName="full_name"
|
||
:filters="[selectedMember]"
|
||
@remove-filter="removeFromUserFilter"
|
||
></filter-list>
|
||
</div>
|
||
|
||
<button
|
||
@click.prevent="showIssueProperties = true"
|
||
class="btn selected-filter-list"
|
||
type="button"
|
||
>
|
||
<svg class="icon icon-eye"><use xlink:href="#icon-eye"></use></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="d-flex">
|
||
<div
|
||
id="paste-section"
|
||
class="comment-list position-relative"
|
||
:class="{ 'replays-is-open': isMainEditMode }"
|
||
>
|
||
<div
|
||
:class="{ show: showSelectionActionBar }"
|
||
class="select-options d-flex align-items-center justify-content-between mx-2"
|
||
>
|
||
<div class="d-flex align-items-center py-1">
|
||
<div class="custom-control custom-checkbox">
|
||
<input
|
||
type="checkbox"
|
||
class="custom-control-input"
|
||
id="select-all-checkbox"
|
||
v-model="checked"
|
||
@change="selectAllCheckbox"
|
||
/>
|
||
<label
|
||
class="custom-control-label"
|
||
for="select-all-checkbox"
|
||
></label>
|
||
</div>
|
||
|
||
<span class="mx-4 text-start" dir="ltr"
|
||
>{{ selectedCommentsId.length }}<small>x</small></span
|
||
>
|
||
|
||
<div class="selection-actions">
|
||
<!-- <button
|
||
disabled="true"
|
||
type="button"
|
||
class="btn btn-outline-secondary ms-2"
|
||
>
|
||
انتقال
|
||
</button>
|
||
<button
|
||
disabled="true"
|
||
type="button"
|
||
class="btn btn-outline-secondary ms-2"
|
||
>
|
||
خروجی
|
||
</button> -->
|
||
<!-- <button
|
||
disabled="true"
|
||
type="button"
|
||
class="btn btn-outline-secondary ms-2"
|
||
>
|
||
آرشیو
|
||
</button> -->
|
||
<button-component
|
||
@click="deleteMany()"
|
||
classes="btn-outline-danger"
|
||
buttonText="حذف"
|
||
:buttonLoading="buttonLoading"
|
||
></button-component>
|
||
</div>
|
||
</div>
|
||
<button-component
|
||
@click="unSelectAllMessages()"
|
||
buttonText="انصراف"
|
||
title="انصراف"
|
||
classes="d-flex align-items-center text-danger"
|
||
>
|
||
<svg class="icon icon-error">
|
||
<use xlink:href="#icon-error"></use>
|
||
</svg>
|
||
|
||
<!-- <i style="font-size:0.9rem;color:inherit;" class="tavasi tavasi-Component-294--1"></i> -->
|
||
<!-- <span style="font-size:1rem" >بستن</span> -->
|
||
</button-component>
|
||
</div>
|
||
|
||
<div
|
||
id="comments"
|
||
class="comments"
|
||
ref="messages"
|
||
:class="{ 'show-drad-effects': dragStarted }"
|
||
>
|
||
<drop
|
||
class="drop"
|
||
@dragleave="handleDragLeave"
|
||
@drop="handleDrop"
|
||
@dragover="handleDragEnter($event, 'messages')"
|
||
>
|
||
<div v-if="canView">
|
||
<the-content-loading
|
||
class="absolute-positioning"
|
||
v-if="fetchingData"
|
||
></the-content-loading>
|
||
|
||
<div v-else>
|
||
<!-- <div v-if="localComments && localComments.length"> -->
|
||
<virtual-list
|
||
:estimate-size="200"
|
||
class="stream scroll-touch"
|
||
:class="[
|
||
{ overflow: overflow },
|
||
{ 'filter-is-active': selectedLabel || selectedMember },
|
||
]"
|
||
ref="vsl"
|
||
:data-key="'id'"
|
||
:data-sources="localComments"
|
||
:data-component="itemComponent"
|
||
:start="150"
|
||
@totop="toTop()"
|
||
@tobottom="toBottom()"
|
||
:extra-props="{
|
||
selectedCommentsId: selectedCommentsId,
|
||
showSelectionActionBar: showSelectionActionBar,
|
||
replayUsers: replayUsers,
|
||
showCardReplays: true,
|
||
replayFrom: 'messages',
|
||
editFrom: 'isMainEditMode',
|
||
}"
|
||
>
|
||
<div slot="header" v-show="overflow" class="header">
|
||
<div class="spinner" v-show="!finished_top"></div>
|
||
<div class="finished" v-show="finished_top">
|
||
No more data
|
||
</div>
|
||
</div>
|
||
</virtual-list>
|
||
<div class="empty" v-show="!localComments.length">
|
||
<div class="wrapper">
|
||
<div class="icon"></div>
|
||
<div class="tips">No chats</div>
|
||
</div>
|
||
</div>
|
||
<!-- </div> -->
|
||
<!-- <no-data v-else></no-data> -->
|
||
</div>
|
||
</div>
|
||
<no-data v-else>
|
||
<the-content-loading v-if="fetchingData"></the-content-loading>
|
||
|
||
<div
|
||
v-else
|
||
class="d-flex justify-content-center align-items-center"
|
||
>
|
||
<div
|
||
class="alert alert-warning d-flex justify-content-center align-items-center"
|
||
>
|
||
<span
|
||
class="tavasi tavasi-warning-circle color-inherit ms-1 text__32"
|
||
></span>
|
||
عدم دسترسی
|
||
</div>
|
||
</div>
|
||
</no-data>
|
||
</drop>
|
||
|
||
<div
|
||
v-if="showDroppedList && dropBoxClass == 'messages'"
|
||
class="dropped-list"
|
||
:class="[dropBoxClass, { uploading: uploading }]"
|
||
>
|
||
<div class="heading-part mb-2">
|
||
<button
|
||
type="button"
|
||
class="btn"
|
||
@click.prevent="closeDroppedList()"
|
||
:disabled="uploading"
|
||
>
|
||
<svg class="icon icon-Component-294--1">
|
||
<use xlink:href="#icon-Component-294--1"></use>
|
||
</svg>
|
||
</button>
|
||
<span class="flex-grow-1"> ارسال فایل </span>
|
||
|
||
<button
|
||
type="button"
|
||
class="btn btn-primary"
|
||
@click.prevent="mainSaveFiles()"
|
||
>
|
||
ارسال
|
||
</button>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<textarea
|
||
v-model="uploadDescription"
|
||
name="upload-description"
|
||
id="upload-description"
|
||
cols="30"
|
||
rows="3"
|
||
class="form-control"
|
||
placeholder="توضیحاتی برای فایل وارد نمایید."
|
||
></textarea>
|
||
<!-- <input
|
||
type="text"
|
||
class="form-control"
|
||
placeholder="عنوانی برای فایل وارد نمایید."
|
||
v-model="uploadDescription"
|
||
/> -->
|
||
</div>
|
||
|
||
<div v-if="showMobileUploadButton" class="form-group">
|
||
<div class="image-uploader-container">
|
||
<image-uploader
|
||
:accept="acceptTypes"
|
||
ref="file-uploader"
|
||
:preview="false"
|
||
:debug="1"
|
||
:maxWidth="300"
|
||
:maxHeight="300"
|
||
:maxSize="2"
|
||
:quality="1"
|
||
:autoRotate="true"
|
||
outputFormat="file"
|
||
:className="['fileinput', { 'fileinput--loaded': hasImage }]"
|
||
:capture="false"
|
||
@input="setImage"
|
||
@onUpload="startUploading"
|
||
@onComplete="endOfUploading"
|
||
>
|
||
<label
|
||
class="upload-label"
|
||
for="fileInput"
|
||
slot="upload-label"
|
||
>
|
||
<!-- <img
|
||
v-if="
|
||
files?.length &&
|
||
(getFileExtension(files[0].name) == 'png' ||
|
||
getFileExtension(files[0].name) == 'jpg' ||
|
||
getFileExtension(files[0].name) == 'jpeg')
|
||
"
|
||
:src="files"
|
||
class="img-fluid"
|
||
:alt="files.name"
|
||
/>
|
||
|
||
<span
|
||
v-else-if="files?.length"
|
||
class="tavasi"
|
||
:class="`tavasi-${getFileExtension(files[0].name)}-file`"
|
||
></span> -->
|
||
|
||
<!-- replace image src with incoming src -->
|
||
|
||
<!-- <span v-else class="tavasi tavasi-cloud-upload"></span> -->
|
||
<span class="tavasi tavasi-cloud-upload"></span>
|
||
</label>
|
||
</image-uploader>
|
||
</div>
|
||
</div>
|
||
|
||
<ol type="1" class="file-list">
|
||
<li
|
||
class="file-list-item"
|
||
v-for="(file, index) in files"
|
||
:key="index"
|
||
>
|
||
<div class="d-flex align-items-center py-3 px-1">
|
||
<span class="file-icon-container">
|
||
<svg :class="'icon icon-' + fileIcon(file.type)">
|
||
<use :xlink:href="'#icon-' + fileIcon(file.type)"></use>
|
||
</svg>
|
||
</span>
|
||
|
||
<div class="me-3 flex-grow-1">
|
||
<h6>
|
||
{{ file.name }}
|
||
</h6>
|
||
<p class="m-0">
|
||
{{ formatBytes(file.size) }}
|
||
</p>
|
||
</div>
|
||
|
||
<button
|
||
type="button"
|
||
class="btn c-btn-danger"
|
||
@click.prevent="removeFile(file, index)"
|
||
>
|
||
<svg class="icon icon-Component-295--1">
|
||
<use xlink:href="#icon-Component-295--1"></use>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</li>
|
||
</ol>
|
||
|
||
<div class="form-group" v-if="pasting && showReplays">
|
||
<div class="custom-checkbox-container position-static">
|
||
<div class="custom-control custom-checkbox">
|
||
<input
|
||
type="checkbox"
|
||
class="custom-control-input"
|
||
v-model="saveAs"
|
||
true-value="replay"
|
||
false-value="message"
|
||
id="save-as"
|
||
/>
|
||
<label class="custom-control-label pe-1" for="save-as"
|
||
>ذخیره به عنوان پاسخ</label
|
||
>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="uploading" class="uploading-animation">
|
||
<the-content-loading class="position-static">
|
||
در حال بارگزاری فایل ...
|
||
</the-content-loading>
|
||
</div>
|
||
</div>
|
||
|
||
<div
|
||
v-if="dragStarted && dropBoxClass == 'messages'"
|
||
class="drop-container"
|
||
:class="dropBoxClass"
|
||
>
|
||
<span> فایل ها را جهت ارسال اینجا رها کنید. </span>
|
||
</div>
|
||
|
||
<div class="first-last-button">
|
||
<button-component
|
||
title="برو به اولین پیام"
|
||
@click="tofirstItem()"
|
||
classes="go-first"
|
||
buttonText=""
|
||
>
|
||
<svg class="icon icon-Component-25--1">
|
||
<use xlink:href="#icon-Component-25--1"></use>
|
||
</svg>
|
||
</button-component>
|
||
|
||
<button-component
|
||
@click="toLastItem()"
|
||
title="برو به آخرین پیام"
|
||
classes="go-last"
|
||
buttonText=""
|
||
>
|
||
<svg class="icon icon-Component-25--1">
|
||
<use xlink:href="#icon-Component-25--1"></use>
|
||
</svg>
|
||
</button-component>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- comment form -->
|
||
<div class="comment-form-container">
|
||
<div v-if="listGetter?.show_joined" class="join-group">
|
||
<button-component
|
||
classes="btn-outline-primary join-button"
|
||
title="پیوستن به گروه"
|
||
buttonText="پبوستن به گروه"
|
||
@click="openAuthModal()"
|
||
>
|
||
</button-component>
|
||
<!-- <button-component
|
||
classes="me-2"
|
||
title="انصراف"
|
||
buttonText="انصراف"
|
||
@click="cancelJoin"
|
||
>
|
||
</button-component> -->
|
||
</div>
|
||
|
||
<div v-else>
|
||
<div
|
||
ref="replyComment"
|
||
class="footer-reply_comment"
|
||
v-if="isMainEditMode"
|
||
>
|
||
<div class="d-flex align-items-center">
|
||
<span class="tavasi" :class="iconClass"></span>
|
||
|
||
<div class="p-1">
|
||
<p
|
||
v-if="isForward"
|
||
class="mb-1 text__13"
|
||
style="color: #00b6e3"
|
||
>
|
||
هدایت پیام
|
||
</p>
|
||
|
||
<div v-if="getForwardItem?.type == 'Private'">
|
||
<h6 class="commentor-name">
|
||
<span v-if="isForward">@</span
|
||
>{{ getForwardItem?.message.user?.username }}
|
||
<!-- @{{ userFullname(mainCommentor.user) }} -->
|
||
</h6>
|
||
|
||
<p class="commentor-text">
|
||
{{
|
||
JSON.parse(
|
||
JSON.stringify(getForwardItem?.message?.text)
|
||
)
|
||
}}
|
||
</p>
|
||
</div>
|
||
|
||
<div v-else>
|
||
<!-- <h6 class="commentor-name">
|
||
<span v-if="isForward">@</span
|
||
>{{ mainCommentor?.title }}
|
||
</h6> -->
|
||
<p class="commentor-text">
|
||
{{ JSON.parse(JSON.stringify(mainCommentor?.text)) }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<button
|
||
type="button"
|
||
class="btn p-0"
|
||
@click.prevent="closeComments('isMainEditMode')"
|
||
>
|
||
<span class="tavasi tavasi-Component-294--1"></span>
|
||
</button>
|
||
</div>
|
||
|
||
<form
|
||
@submit.prevent="save($event, 'mainTextAreaInput', 'messages')"
|
||
class="comment-form"
|
||
>
|
||
<my-audio-recorder @send="onResult"></my-audio-recorder>
|
||
<!-- <my-plugin-audio-recorder @send="onResult"></my-plugin-audio-recorder> -->
|
||
|
||
<div class="input-group" dir="ltr">
|
||
<div dir="rtl" class="input-group-prepend">
|
||
<button
|
||
@click.prevent="openUploadForm('messages')"
|
||
class="btn ps-3"
|
||
type="button"
|
||
id="button-addon2"
|
||
>
|
||
<span class="tavasi tavasi-Component-69--1"></span>
|
||
</button>
|
||
</div>
|
||
<!-- <div dir="rtl" class="input-group-prepend">
|
||
<button class="btn p-1" type="button" id="button-addon2">
|
||
<span class="tavasi tavasi-Component-305--1"></span>
|
||
</button>
|
||
</div>
|
||
<div dir="rtl" class="input-group-prepend">
|
||
<button class="btn" type="button" id="button-addon2">
|
||
<span class="tavasi tavasi-at-sign"></span>
|
||
</button>
|
||
</div> -->
|
||
<textarea
|
||
ref="mainTextAreaInput"
|
||
@keyup.exact.escape="closeComments('isMainEditMode')"
|
||
@keyup.exact.enter="
|
||
save($event, 'mainTextAreaInput', 'messages')
|
||
"
|
||
dir="rtl"
|
||
placeholder="پیامتو بنویس"
|
||
lass="form-control"
|
||
v-model="userMessage"
|
||
class="form-control textform"
|
||
name="user-comment"
|
||
id="user-comment"
|
||
cols="30"
|
||
rows="1"
|
||
></textarea>
|
||
<div dir="rtl" class="input-group-append">
|
||
<button-component
|
||
type="submit"
|
||
title="ارسال"
|
||
classes="btn"
|
||
buttonText=""
|
||
:disabled="savingComment"
|
||
:buttonLoading="savingComment"
|
||
>
|
||
<span class="tavasi tavasi-Component-236--1"></span>
|
||
|
||
<!-- <span v-else class="tavasi tavasi-Component-85--1" -->
|
||
<!-- ><span class="path1"></span><span class="path2"></span -->
|
||
<!-- ></span> -->
|
||
</button-component>
|
||
<!-- <button type="button" class="btn" v-else>
|
||
<vue-record-audio
|
||
:key="refreshRecorder"
|
||
mode="press"
|
||
@stream="onStream"
|
||
@result="onResult"
|
||
></vue-record-audio>
|
||
</button> -->
|
||
|
||
<!-- <button-component
|
||
v-if="recording"
|
||
title="حذف"
|
||
classes="remove-record"
|
||
buttonText=""
|
||
:class="{ recording: recording }"
|
||
@click="removeRecordFile()"
|
||
>
|
||
<svg class="icon icon-Component-295--1">
|
||
<use xlink:href="#icon-Component-295--1"></use>
|
||
</svg>
|
||
</button-component> -->
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- replay list box -->
|
||
<div
|
||
id="replays"
|
||
v-if="showReplays"
|
||
class="position-relative"
|
||
:class="{ show: showReplays }"
|
||
>
|
||
<div class="replay-head">
|
||
<div>
|
||
<p class="group-title">
|
||
<!-- پاسخ به: -->
|
||
<!-- <strong style> -->
|
||
{{ listGetter?.title }}
|
||
<!-- </strong> -->
|
||
</p>
|
||
<p
|
||
class="group-description"
|
||
v-html="groupDescription(replayTo.text)"
|
||
></p>
|
||
</div>
|
||
|
||
<div class="d-flex">
|
||
<button @click.prevent="closeReplays()" type="button" class="btn">
|
||
<span class="tavasi tavasi-Component-294--1"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div
|
||
class="replay-list position-relative"
|
||
ref="replays"
|
||
:class="{ 'replay-comment-is-open': isReplayEditMode }"
|
||
>
|
||
<drop
|
||
class="drop"
|
||
@dragleave="handleDragLeave"
|
||
@drop="handleDrop"
|
||
@dragover="handleDragEnter($event, 'replays')"
|
||
>
|
||
<the-content-loading
|
||
class="absolute-positioning"
|
||
v-if="fetchinReplaygData"
|
||
></the-content-loading>
|
||
|
||
<div v-else>
|
||
<!-- <div v-if="replays && replays.length"> -->
|
||
<virtual-list
|
||
:estimate-size="200"
|
||
class="stream scroll-touch replays-scroll"
|
||
:class="[
|
||
{ overflow: overflow },
|
||
{ 'filter-is-active': selectedLabel || selectedMember },
|
||
]"
|
||
ref="replayVsl"
|
||
:data-key="'id'"
|
||
:data-sources="replays"
|
||
:data-component="itemComponent"
|
||
:start="150"
|
||
@totop="replayToTop('replays', 'isReplayEditMode')"
|
||
@tobottom="replayToBottom('replays', 'isReplayEditMode')"
|
||
:extra-props="{
|
||
replayFrom: 'replays',
|
||
editFrom: 'isReplayEditMode',
|
||
}"
|
||
>
|
||
<div slot="header" v-show="overflow" class="header">
|
||
<div class="spinner" v-show="!finished_top"></div>
|
||
<div class="finished" v-show="finished_top">No more data</div>
|
||
</div>
|
||
</virtual-list>
|
||
<div class="empty" v-show="!replays.length">
|
||
<div class="wrapper">
|
||
<div class="icon"></div>
|
||
<div class="tips">No chats</div>
|
||
</div>
|
||
</div>
|
||
<!-- </div> -->
|
||
<!-- <no-data v-else></no-data> -->
|
||
|
||
<!-- <div v-if="replays.length">
|
||
<chat-list-item
|
||
v-for="(comment, key) in replays"
|
||
:key="key"
|
||
:comment="comment"
|
||
@replay-comment="replyComments"
|
||
@delete-replay="deleteItem(replays, comment, key)"
|
||
@edit-replay="
|
||
editComment(comment, 'replays', 'isReplayEditMode')
|
||
"
|
||
></chat-list-item>
|
||
</div>
|
||
<no-data v-else></no-data> -->
|
||
</div>
|
||
</drop>
|
||
</div>
|
||
<div class="comment-form-container">
|
||
<div
|
||
ref="replyComment"
|
||
class="footer-reply_comment"
|
||
v-if="replyComment || isReplayEditMode"
|
||
>
|
||
<div class="d-flex align-items-center">
|
||
<span class="tavasi" :class="iconClass"></span>
|
||
|
||
<div class="p-1">
|
||
<h6 class="commentor-name">
|
||
{{ userFullname(replayCommentor.user) }}
|
||
</h6>
|
||
<p class="commentor-text">{{ replayCommentor.text }}</p>
|
||
</div>
|
||
</div>
|
||
|
||
<button
|
||
type="button"
|
||
class="btn p-0"
|
||
@click.prevent="closeReplyComment('isReplayEditMode')"
|
||
>
|
||
<span class="tavasi tavasi-Component-294--1"></span>
|
||
</button>
|
||
</div>
|
||
|
||
<form
|
||
@submit.prevent="saveReplay($event, 'replayTextRef', 'replays')"
|
||
class="comment-form"
|
||
>
|
||
<my-audio-recorder @send="replayOnResult"></my-audio-recorder>
|
||
|
||
<div class="input-group" dir="ltr">
|
||
<div dir="rtl" class="input-group-prepend">
|
||
<button
|
||
@click.prevent="openUploadForm('replays')"
|
||
class="btn ps-3"
|
||
type="button"
|
||
id="button-addon2"
|
||
>
|
||
<span class="tavasi tavasi-Component-69--1"></span>
|
||
</button>
|
||
</div>
|
||
<!-- <div dir="rtl" class="input-group-prepend">
|
||
<button class="btn p-1" type="button" id="button-addon2">
|
||
<span class="tavasi tavasi-Component-305--1"></span>
|
||
</button>
|
||
</div> -->
|
||
<!-- <div dir="rtl" class="input-group-prepend">
|
||
<button class="btn" type="button" id="button-addon2">
|
||
<span class="tavasi tavasi-at-sign"></span>
|
||
</button>
|
||
</div> -->
|
||
<textarea
|
||
ref="replayTextRef"
|
||
@keyup.exact.enter="
|
||
saveReplay($event, 'replayTextRef', 'replays')
|
||
"
|
||
@keyup.exact.escape="closeReplyComment('isReplayEditMode')"
|
||
dir="rtl"
|
||
placeholder="پیامتو بنویس"
|
||
lass="form-control"
|
||
v-model="replayText"
|
||
class="form-control textform"
|
||
name="user-comment"
|
||
id="user-comment2"
|
||
cols="30"
|
||
rows="1"
|
||
></textarea>
|
||
<div dir="rtl" class="input-group-append">
|
||
<button-component
|
||
type="submit"
|
||
title="ارسال"
|
||
classes="btn"
|
||
buttonText=""
|
||
:disabled="savingReplay"
|
||
:buttonLoading="savingReplay"
|
||
>
|
||
<span class="tavasi tavasi-Component-236--1"></span>
|
||
|
||
<!-- <span v-else class="tavasi tavasi-Component-85--1" -->
|
||
<!-- ><span class="path1"></span><span class="path2"></span -->
|
||
<!-- ></span> -->
|
||
</button-component>
|
||
<!-- <button type="button" class="btn" v-else>
|
||
<vue-record-audio
|
||
:key="replayRefreshRecorder"
|
||
mode="press"
|
||
@stream="replayOnStream"
|
||
@result="replayOnResult"
|
||
></vue-record-audio>
|
||
</button> -->
|
||
|
||
<!-- <button-component
|
||
v-if="replayRecording"
|
||
title="حذف"
|
||
classes="remove-record"
|
||
buttonText=""
|
||
:class="{ recording: replayRecording }"
|
||
@click="replayRemoveRecordFile()"
|
||
>
|
||
<svg class="icon icon-Component-295--1">
|
||
<use xlink:href="#icon-Component-295--1"></use>
|
||
</svg>
|
||
</button-component> -->
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<div
|
||
v-if="showDroppedList && dropBoxClass == 'replays'"
|
||
class="dropped-list"
|
||
:class="dropBoxClass"
|
||
>
|
||
<div class="heading-part mb-2">
|
||
<button
|
||
type="button"
|
||
class="btn"
|
||
@click.prevent="closeDroppedList()"
|
||
>
|
||
<svg class="icon icon-Component-294--1">
|
||
<use xlink:href="#icon-Component-294--1"></use>
|
||
</svg>
|
||
</button>
|
||
<span class="flex-grow-1"> ارسال فایل </span>
|
||
|
||
<button
|
||
type="button"
|
||
class="btn btn-primary"
|
||
@click.prevent="replaySaveFiles()"
|
||
>
|
||
ارسال
|
||
</button>
|
||
</div>
|
||
<div class="form-group">
|
||
<textarea
|
||
v-model="uploadDescription"
|
||
name="upload-description"
|
||
id="upload-description"
|
||
cols="30"
|
||
rows="3"
|
||
class="form-control"
|
||
placeholder="توضیحاتی برای فایل وارد نمایید."
|
||
></textarea>
|
||
|
||
<!-- <input
|
||
type="text"
|
||
class="form-control"
|
||
placeholder="عنوانی برای فایل وارد نمایید."
|
||
v-model="uploadDescription"
|
||
/> -->
|
||
</div>
|
||
<ol type="1" class="file-list">
|
||
<li
|
||
class="file-list-item"
|
||
v-for="(file, index) in files"
|
||
:key="index"
|
||
>
|
||
<div class="d-flex align-items-center py-3 px-1">
|
||
<span class="file-icon-container">
|
||
<svg :class="'icon icon-' + fileIcon(file.type)">
|
||
<use :xlink:href="'#icon-' + fileIcon(file.type)"></use>
|
||
</svg>
|
||
</span>
|
||
|
||
<div class="me-3 flex-grow-1">
|
||
<h6>
|
||
{{ file.name }}
|
||
</h6>
|
||
<p class="m-0">
|
||
{{ formatBytes(file.size) }}
|
||
</p>
|
||
</div>
|
||
|
||
<button
|
||
type="button"
|
||
class="btn c-btn-danger"
|
||
@click.prevent="removeFile(file, index)"
|
||
>
|
||
<svg class="icon icon-Component-295--1">
|
||
<use xlink:href="#icon-Component-295--1"></use>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</li>
|
||
</ol>
|
||
|
||
<!-- upload button -->
|
||
<!-- <form class="d-xl-none">
|
||
<div class="form-group">
|
||
<h5>بارگزاری فایل</h5>
|
||
</div> -->
|
||
|
||
<div v-if="showMobileUploadButton" class="form-group">
|
||
<div class="image-uploader-container">
|
||
<image-uploader
|
||
:accept="acceptTypes"
|
||
ref="file-uploader"
|
||
:preview="false"
|
||
:debug="1"
|
||
:maxWidth="300"
|
||
:maxHeight="300"
|
||
:maxSize="2"
|
||
:quality="1"
|
||
:autoRotate="true"
|
||
outputFormat="file"
|
||
:className="['fileinput', { 'fileinput--loaded': hasImage }]"
|
||
:capture="false"
|
||
@input="setImage"
|
||
@onUpload="startUploading"
|
||
@onComplete="endOfUploading"
|
||
>
|
||
<label class="upload-label" for="fileInput" slot="upload-label">
|
||
<!-- <img
|
||
v-if="
|
||
files?.length &&
|
||
(getFileExtension(files[0].name) == 'png' ||
|
||
getFileExtension(files[0].name) == 'jpg' ||
|
||
getFileExtension(files[0].name) == 'jpeg')
|
||
"
|
||
:src="files"
|
||
class="img-fluid"
|
||
:alt="files.name"
|
||
/> -->
|
||
|
||
<!-- <span
|
||
v-else-if="files?.length"
|
||
class="tavasi"
|
||
:class="`tavasi-${getFileExtension(files[0].name)}-file`"
|
||
></span> -->
|
||
|
||
<!-- replace image src with incoming src -->
|
||
|
||
<!-- <span v-else class="tavasi tavasi-cloud-upload"></span> -->
|
||
<span class="tavasi tavasi-cloud-upload"></span>
|
||
</label>
|
||
</image-uploader>
|
||
</div>
|
||
</div>
|
||
<!-- </form> -->
|
||
</div>
|
||
|
||
<div
|
||
v-if="dragStarted && dropBoxClass == 'replays'"
|
||
class="drop-container d-none d-xl-flex"
|
||
:class="dropBoxClass"
|
||
>
|
||
<span> فایل ها را جهت ارسال اینجا رها کنید. </span>
|
||
</div>
|
||
|
||
<!-- upload group/lobby avatar -->
|
||
</div>
|
||
|
||
<!-- #region issue -->
|
||
<div
|
||
id="replays"
|
||
v-if="showIssueProperties"
|
||
class="position-relative"
|
||
:class="{ show: showIssueProperties }"
|
||
>
|
||
<div class="replay-head">
|
||
<div>
|
||
<p class="group-title m-0">
|
||
فیلتر شده براساس:
|
||
<strong style>
|
||
{{ selectedLabel?.lable }}
|
||
</strong>
|
||
</p>
|
||
</div>
|
||
|
||
<div class="d-flex">
|
||
<button
|
||
@click.prevent="closeIssueProperties()"
|
||
type="button"
|
||
class="btn d-flex"
|
||
>
|
||
<span class="tavasi tavasi-Component-294--1"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div
|
||
class="replay-list position-relative"
|
||
ref="replays"
|
||
:class="{ 'replay-comment-is-open': showIssueProperties }"
|
||
>
|
||
<div class="drop">
|
||
<div
|
||
class="stream scroll-touch replays-scroll"
|
||
:class="[{ 'filter-is-active': selectedLabel || selectedMember }]"
|
||
>
|
||
<!-- :is="issueProperty[selectedLabel.entity_field_id]" -->
|
||
<component
|
||
v-if="selectedLabel?.key && issue[selectedLabel?.key]"
|
||
:enableComments="false"
|
||
:sections="issueSections"
|
||
:entityContent="selectedLabel"
|
||
:is="entityFieldsGetter(selectedLabel.entity_field_id)"
|
||
:propertyName="selectedLabel.key"
|
||
:rootCommentId="listGetter?.reference_id"
|
||
:updateKey="false"
|
||
:entity="issue"
|
||
:comments="[]"
|
||
:showComments="false"
|
||
class="vertical"
|
||
:carouselItems="1"
|
||
/>
|
||
|
||
<!-- {{ issue[selectedLabel.key] }} -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- #endregino -->
|
||
|
||
<div v-if="showMobileActions" class="mobile-actions">
|
||
<div class="d-flex justify-content-between p-3 border-bottom">
|
||
<h5 class="m-0">عملیات</h5>
|
||
|
||
<button
|
||
@click.prevent="showMobileActions = false"
|
||
class="btn d-flex"
|
||
type="button"
|
||
>
|
||
<span
|
||
style="transform: rotate(180deg); display: inline-block"
|
||
class="tavasi tavasi-Component-71--1"
|
||
></span>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="p-3">
|
||
<div class="d-flex justify-content-center mb-3">
|
||
<a
|
||
v-if="listGetter?.reference_id && isIssueGroup()"
|
||
:href="'/jahat/' + buttonName + '/' + listGetter?.reference_id"
|
||
:title="buttonTitle"
|
||
@click.prevent="goToJahat()"
|
||
class="btn btn-outline-primary"
|
||
>
|
||
{{ buttonTitle }}
|
||
</a>
|
||
<a
|
||
v-if="listGetter?.reference_id && isAnswerGroup()"
|
||
:href="
|
||
'/jahat/answers/' +
|
||
listGetter.parent_reference +
|
||
'/' +
|
||
listGetter?.reference_id
|
||
"
|
||
:title="buttonTitle"
|
||
@click.prevent="goToJahat()"
|
||
class="btn btn-outline-primary"
|
||
>
|
||
{{ buttonTitle }}
|
||
</a>
|
||
</div>
|
||
<multiselect
|
||
v-model="selectedLabel"
|
||
class="mb-3"
|
||
id="labels"
|
||
track-by="entity_field_id"
|
||
placeholder="فیلتر برچسب ها"
|
||
label="lable"
|
||
:multiple="false"
|
||
:options="listGetter?.entity_labels ?? []"
|
||
:allow-empty="true"
|
||
:searchable="true"
|
||
:options-limit="300"
|
||
:limit="10"
|
||
:limit-text="limitText"
|
||
:max-height="350"
|
||
@select="filterMessagesBySection"
|
||
@remove="filterMessagesBySection(undefined)"
|
||
selectLabel=""
|
||
selectedLabel=""
|
||
deselectLabel=""
|
||
:close-on-select="true"
|
||
:clear-on-select="false"
|
||
:preserve-search="true"
|
||
>
|
||
<div slot="selection" slot-scope="{ values, search, isOpen }">
|
||
<span
|
||
class="multiselect__single"
|
||
v-if="values.length"
|
||
v-show="!isOpen"
|
||
>{{ values.length }} فیلتر</span
|
||
>
|
||
</div>
|
||
<div slot="noResult" slot-scope="{ values, search, isOpen }">
|
||
چیزی یافت نشد.
|
||
</div>
|
||
<div slot="noOptions" slot-scope="{ values, search, isOpen }">
|
||
فهرست خالی است.
|
||
</div>
|
||
<!-- <div slot="beforeList" slot-scope="{ values, search, isOpen }">
|
||
beforeList
|
||
</div>
|
||
<div slot="afterList" slot-scope="{ values, search, isOpen }">
|
||
afterList
|
||
</div> -->
|
||
<!-- <div slot="singleLabel" slot-scope="{ values, search, isOpen }">
|
||
singleLabel
|
||
</div>
|
||
-->
|
||
<!-- <div slot="singleLabel" slot-scope="props">
|
||
<span class="option__desc"
|
||
><span class="option__title">{{ props.option.title }}</span></span
|
||
></div
|
||
>
|
||
<div slot="option" slot-scope="props">
|
||
<div class="option__desc">
|
||
<span class="option__title">{{ props.option.lable }}</span>
|
||
</div>
|
||
</div> -->
|
||
</multiselect>
|
||
<div class="multiselect-container">
|
||
<span class="badge badge-primary" title="تعداد اعضاء">
|
||
{{ groupMember?.length ?? 0 }}
|
||
</span>
|
||
<multiselect
|
||
v-model="selectedMember"
|
||
id="members"
|
||
class="mb-3"
|
||
track-by="user_id"
|
||
placeholder="فیلتر کاربران"
|
||
:show-labels="false"
|
||
:options="groupMember"
|
||
:searchable="true"
|
||
:allow-empty="true"
|
||
:close-on-select="true"
|
||
:options-limit="300"
|
||
:limit="3"
|
||
:limit-text="limitText"
|
||
:max-height="350"
|
||
:customLabel="
|
||
(item) => {
|
||
return `${item.full_name}`;
|
||
}
|
||
"
|
||
@select="filterMessagesByUser"
|
||
@remove="filterMessagesByUser(undefined)"
|
||
>
|
||
</multiselect>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="showAuthModal" class="custom-auth-modal auth-page">
|
||
<!-- Vertically centered scrollable modal -->
|
||
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="exampleModalLabel">
|
||
{{ $t("LoginForm") }}
|
||
</h5>
|
||
<button
|
||
type="button"
|
||
class="close ms-0 me-auto"
|
||
data-dismiss="modal"
|
||
aria-label="Close"
|
||
@click.prevent="closeAuthModal()"
|
||
>
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="modal-body">
|
||
<div class="authentication-styles">
|
||
<auth-component></auth-component>
|
||
</div>
|
||
</div>
|
||
<!-- <div class="modal-footer">
|
||
<button
|
||
type="button"
|
||
class="btn btn-secondary"
|
||
data-dismiss="modal"
|
||
>
|
||
Close
|
||
</button>
|
||
<button type="button" class="btn btn-primary">Save changes</button>
|
||
</div> -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<base-modal
|
||
v-if="showForwardModal"
|
||
modalSize="modal-md"
|
||
modalTitle="هدایت به ..."
|
||
:hasFooter="false"
|
||
@close="closeAndResetForwardModal"
|
||
>
|
||
<user-search @forward="redirectToPrivates"></user-search>
|
||
</base-modal>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
// import Vue from "vue";
|
||
// import VueRecord from "@codekraft-studio/vue-record";
|
||
import { mapState, mapActions } from "pinia";
|
||
import { useChatStore } from "@chat/stores/chatStore";
|
||
import { useCommonStore } from "@stores/commonStore";
|
||
import chatApi from "@chat/apis/chatApi";
|
||
|
||
import replayMixin from "@chat/mixins/replayMixin";
|
||
import createdMixin from "@chat/mixins/createdMixin";
|
||
import mountedMixin from "@chat/mixins/mountedMixin";
|
||
import fileMixin from "@chat/mixins/fileMixin";
|
||
import virtialListMixin from "@chat/mixins/virtialListMixin";
|
||
import headerMixin from "@chat/mixins/headerMixin";
|
||
import jahatMixin from "@chat/mixins/jahatMixin";
|
||
import forwardMixin from "@chat/mixins/forwardMixin";
|
||
import commonMixin from "@chat/mixins/commonMixin";
|
||
import messageMixin from "@chat/mixins/messageMixin";
|
||
|
||
// import lobbiesContextMenu from "~/json/chat/json/lobbiesContextMenu.json";
|
||
// import VirtualList from "vue-virtual-scroll-list";
|
||
import ChatListItem from "@chat/components/chat/components/ChatListItem";
|
||
|
||
import entityFields from "@chat/json/entityFields.json";
|
||
|
||
// Vue.use(VueRecord);
|
||
|
||
export default {
|
||
name: "chat-list",
|
||
mixins: [
|
||
commonMixin,
|
||
createdMixin,
|
||
fileMixin,
|
||
forwardMixin,
|
||
headerMixin,
|
||
jahatMixin,
|
||
messageMixin,
|
||
mountedMixin,
|
||
replayMixin,
|
||
virtialListMixin,
|
||
],
|
||
|
||
beforeMount() {
|
||
this.initServices();
|
||
},
|
||
watch: {
|
||
$route: {
|
||
handler: function (to) {
|
||
this.isRedirectedFromOtherSystems = false;
|
||
// this.getAll(to.name);
|
||
},
|
||
deep: true,
|
||
// immediate: true,
|
||
},
|
||
},
|
||
data() {
|
||
return {
|
||
uploading: false,
|
||
entityFields: entityFields,
|
||
acceptTypes: "*",
|
||
// acceptTypes:
|
||
// ".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,image/*,audio/*,video/*",
|
||
showMobileUploadButton: false,
|
||
imageUrl: undefined,
|
||
hasImage: false,
|
||
|
||
labelFilter: [],
|
||
userFilter: [],
|
||
showMobileActions: false,
|
||
|
||
// issueProperty: {
|
||
// 3: "EntityTextContent", // چکیده
|
||
// 5: "EntityTextContent", // بیان
|
||
// 6: "EntityTextContent", // عنوان
|
||
// 9: "EntityTextContent", // هدف
|
||
// 11: "EntityTextContent", // توضیح
|
||
// 10: "EntityTextContent", // روش پیشنهادی
|
||
// 24: "EntityTextContent", // موضوع
|
||
|
||
// 15: "EntityQustionsContent", // سوالات
|
||
|
||
// 14: "EntityListContent", // محصولات
|
||
// 51: "EntityListContent", // معیار
|
||
|
||
// 4: "EntitySliderContent", // ضرورت
|
||
|
||
// 7: "EntitySliderContentTwo", // فایلهای مرتبط
|
||
// 8: "EntitySliderContentTwo", // لینک بیرونی
|
||
|
||
// 13: "EntityHorizontalListContent", // واژه گان
|
||
// 12: "EntityHorizontalListContent", // موضوع
|
||
|
||
// // 6:'EntityFishContent',
|
||
// },
|
||
issueSections: [],
|
||
showAuthModal: false,
|
||
|
||
isAlreadyJoined: true, // show join button if user does not joined yet.
|
||
// showMessageSearch: true, // toggling message search box.
|
||
|
||
commonContextMenu: [],
|
||
lobbiesChildContextMenu: [],
|
||
lobbiesParentContextMenu: [],
|
||
|
||
replayFirstLoad: true, // prevent requesting twice after replay box loaded.
|
||
firstLoad: true, // prevent requesting twice after page loaded.
|
||
buttonName: "",
|
||
buttonTitle: "",
|
||
showList: false,
|
||
// current_row: 0,
|
||
|
||
itemComponent: ChatListItem,
|
||
finished_top: false,
|
||
finished_bottom: false,
|
||
messages: [],
|
||
overflow: false,
|
||
limit: 10,
|
||
|
||
replayOffset: 0,
|
||
replayLimit: 10,
|
||
replayFinishedTop: false,
|
||
replayFinishedBottom: false,
|
||
replayOverflow: false,
|
||
|
||
// #region mehdi
|
||
nomber: 0,
|
||
showFilter: false,
|
||
contextMenuHeader: undefined,
|
||
statusPage: 0,
|
||
// messagesContextMenuHeader: messagesContextMenuHeader,
|
||
// #endregion
|
||
|
||
messageLabel: [],
|
||
selectedMessageLabel: [],
|
||
selectedLabel: undefined,
|
||
|
||
groupMember: [],
|
||
selectedGroupMember: [],
|
||
selectedMember: undefined,
|
||
|
||
busy: false,
|
||
iconTypes: {
|
||
1: "personal",
|
||
2: "groups",
|
||
3: "lobby",
|
||
},
|
||
checked: false,
|
||
showSelectionActionBar: false,
|
||
selectedCommentsId: [],
|
||
prevSelectedItemIndex: 0,
|
||
savingReplay: false,
|
||
replayPagination: {
|
||
page: 0,
|
||
total: 0,
|
||
pageTop: 0,
|
||
pageBottom: 1,
|
||
seenDate: null,
|
||
},
|
||
fetchinReplaygData: false,
|
||
replays: [],
|
||
canView: true,
|
||
replayTo: {},
|
||
pagination: {
|
||
page: 0,
|
||
total: 0,
|
||
pageTop: 0,
|
||
pageBottom: 1,
|
||
seenDate: null,
|
||
},
|
||
messages: [],
|
||
|
||
mainCommentor: {},
|
||
replayCommentor: {},
|
||
|
||
replayText: null,
|
||
showReplays: false,
|
||
|
||
isReplayEditMode: false,
|
||
isMainEditMode: false,
|
||
|
||
fetchingData: false,
|
||
buttonLoading: false,
|
||
replyComment: false,
|
||
replys: {},
|
||
|
||
fileUploadHttpService: undefined,
|
||
httpService: undefined,
|
||
showList: false,
|
||
contextMenu: undefined,
|
||
userMessage: null,
|
||
localComments: [],
|
||
savingComment: false,
|
||
replayUsers: [],
|
||
firstTimeBefore: true,
|
||
firstTimeAfter: false,
|
||
isRedirectedFromOtherSystems: false,
|
||
groupId: undefined,
|
||
messageId: undefined,
|
||
dragStarted: false,
|
||
filenames: [],
|
||
showDroppedList: false,
|
||
files: [],
|
||
uploadDescription: null,
|
||
|
||
recording: false,
|
||
replayRecording: false,
|
||
|
||
abortRecord: false,
|
||
replayAbortRecord: false,
|
||
|
||
refreshRecorder: 1,
|
||
replayRefreshRecorder: 1,
|
||
|
||
dropBoxClass: null,
|
||
saveAs: "message", // checkbox value for saving screen shot as: 1-message 2-replay
|
||
pasting: false, // when user paste something.used for showing dropped list checkbox.
|
||
|
||
showForwardModal: false, // used for showing the redirect modal when user redirect a message.
|
||
selectedItem: {}, // store selected comment when user redirect a message.
|
||
isForward: false, // store selected comment when user redirect a message.
|
||
|
||
isFirstPageReady: false,
|
||
|
||
showIssueProperties: false, // show/hide issues properties.
|
||
issue: {},
|
||
menubarStatus: true,
|
||
mediaStream: null,
|
||
};
|
||
},
|
||
computed: {
|
||
...mapState(useCommonStore, [
|
||
"getPanelStatus",
|
||
"isSidebarCollapsed",
|
||
"sectionsGetter",
|
||
"getForwardItem",
|
||
"currentUser",
|
||
"isGuest",
|
||
"sidebarListStatusGetter",
|
||
]),
|
||
...mapState(useChatStore, ["listGetter"]),
|
||
|
||
amIGroupAdmin() {
|
||
if (this.listGetter?.admins)
|
||
return Boolean(
|
||
this.listGetter?.admins.find((id) => id == this.currentUser.user_id)
|
||
);
|
||
return true;
|
||
},
|
||
iconClass() {
|
||
return this.isMainEditMode ? "tavasi-Component-242--1" : "tavasi-reply";
|
||
},
|
||
sourceGetter() {
|
||
// if (this.$route.name == "privates") {
|
||
// return getGroupAvatar(this.listGetter?.user.avatar);
|
||
// }
|
||
return getGroupAvatar(this.listGetter);
|
||
},
|
||
titleGetter() {
|
||
// if (this.$route.name == "privates") {
|
||
// return userFullname(this.listGetter?.user);
|
||
// }
|
||
return this.listGetter?.title;
|
||
},
|
||
iconGetter() {
|
||
// if (this.$route.name == "privates") {
|
||
// return userFullname(this.listGetter?.user);
|
||
// }
|
||
return this.iconTypes[this.listGetter?.icon_type];
|
||
},
|
||
},
|
||
methods: {
|
||
...mapActions(useCommonStore, [
|
||
"checkPermissions",
|
||
"getUserPermissionTags",
|
||
]),
|
||
...mapActions(useChatStore, [
|
||
"SET_SECTIONS",
|
||
"SET_FORWARD_ITEM",
|
||
"SET_AUTHORIZED_PAGES",
|
||
"SET_USER_PERMISSIONS",
|
||
"SET_SIDEBAR_LIST_STATUS",
|
||
]),
|
||
|
||
fireAddToLobbyEvent() {
|
||
const { $eventBus } = useNuxtApp();
|
||
|
||
$eventBus.emit("add-to-lobby");
|
||
},
|
||
fireCopyLinkEvent() {
|
||
const { $eventBus } = useNuxtApp();
|
||
|
||
$eventBus.emit("copy-link");
|
||
},
|
||
fireEditItemEvent() {
|
||
const { $eventBus } = useNuxtApp();
|
||
|
||
$eventBus.emit("open-edit-item-form");
|
||
},
|
||
fireRemoveItemEvent() {
|
||
const { $eventBus } = useNuxtApp();
|
||
|
||
$eventBus.emit("open-remove-item-modal");
|
||
},
|
||
unSelectAllMessages() {
|
||
this.showSelectionActionBar = false;
|
||
this.selectedCommentsId = [];
|
||
},
|
||
alertUser() {
|
||
alert("ontouchstart");
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
<style lang="scss">
|
||
.multiselect-container {
|
||
position: relative;
|
||
.badge {
|
||
position: absolute;
|
||
left: -5px;
|
||
top: -5px;
|
||
z-index: 9;
|
||
}
|
||
}
|
||
</style>
|