mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-23 16:53:50 +02:00
refactor: app.js (#1291)
* refactor: frontend * Fix avatar gallery sort * Update .NET dependencies * Update npm dependencies electron v37.1.0 * bulkRefreshFriends * fix dark theme * Remove crowdin * Fix config.json dialog not updating * VRCX log file fixes & add Cef log * Remove SharedVariable, fix startup * Revert init theme change * Logging date not working? Fix WinformThemer designer error * Add Cef request hander, no more escaping main page * clean * fix * fix * clean * uh * Apply thememode at startup, fixes random user colours * Split database into files * Instance info remove empty lines * Open external VRC links with VRCX * Electron fixes * fix userdialog style * ohhhh * fix store * fix store * fix: load all group members after kicking a user * fix: world dialog favorite button style * fix: Clear VRCX Cache Timer input value * clean * Fix VR overlay * Fix VR overlay 2 * Fix Discord discord rich presence for RPC worlds * Clean up age verified user tags * Fix playerList being occupied after program reload * no `this` * Fix login stuck loading * writable: false * Hide dialogs on logout * add flush sync option * rm LOGIN event * rm LOGOUT event * remove duplicate event listeners * remove duplicate event listeners * clean * remove duplicate event listeners * clean * fix theme style * fix t * clearable * clean * fix ipcEvent * Small changes * Popcorn Palace support * Remove checkActiveFriends * Clean up * Fix dragEnterCef * Block API requests when not logged in * Clear state on login & logout * Fix worldDialog instances not updating * use <script setup> * Fix avatar change event, CheckGameRunning at startup * Fix image dragging * fix * Remove PWI * fix updateLoop * add webpack-dev-server to dev environment * rm unnecessary chunks * use <script setup> * webpack-dev-server changes * use <script setup> * use <script setup> * Fix UGC text size * Split login event * t * use <script setup> * fix * Update .gitignore and enable checkJs in jsconfig * fix i18n t * use <script setup> * use <script setup> * clean * global types * fix * use checkJs for debugging * Add watchState for login watchers * fix .vue template * type fixes * rm Vue.filter * Cef v138.0.170, VC++ 2022 * Settings fixes * Remove 'USER:CURRENT' * clean up 2FA callbacks * remove userApply * rm i18n import * notification handling to use notification store methods * refactor favorite handling to use favorite store methods and clean up event emissions * refactor moderation handling to use dedicated functions for player moderation events * refactor friend handling to use dedicated functions for friend events * Fix program startup, move lang init * Fix friend state * Fix status change error * Fix user notes diff * fix * rm group event * rm auth event * rm avatar event * clean * clean * getUser * getFriends * getFavoriteWorlds, getFavoriteAvatars * AvatarGalleryUpload btn style & package.json update * Fix friend requests * Apply user * Apply world * Fix note diff * Fix VR overlay * Fixes * Update build scripts * Apply avatar * Apply instance * Apply group * update hidden VRC+ badge * Fix sameInstance "private" * fix 502/504 API errors * fix 502/504 API errors * clean * Fix friend in same instance on orange showing twice in friends list * Add back in broken friend state repair methods * add types --------- Co-authored-by: Natsumi <cmcooper123@hotmail.com>
This commit is contained in:
@@ -26,7 +26,7 @@
|
||||
type="default"
|
||||
size="small"
|
||||
icon="el-icon-upload2"
|
||||
:disabled="!API.currentUser.$isVRCPlus"
|
||||
:disabled="!currentUser.$isVRCPlus"
|
||||
@click="displayGalleryUpload"
|
||||
>{{ t('dialog.gallery_select.upload') }}</el-button
|
||||
>
|
||||
@@ -50,30 +50,27 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, getCurrentInstance } from 'vue';
|
||||
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getCurrentInstance } from 'vue';
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import { vrcPlusImageRequest } from '../../../api';
|
||||
import { useGalleryStore, useUserStore } from '../../../stores';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { $message } = proxy;
|
||||
|
||||
const API = inject('API');
|
||||
const { galleryTable } = storeToRefs(useGalleryStore());
|
||||
const { refreshGalleryTable, handleGalleryImageAdd } = useGalleryStore();
|
||||
const { currentUser } = storeToRefs(useUserStore());
|
||||
|
||||
const props = defineProps({
|
||||
gallerySelectDialog: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
galleryTable: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['refreshGalleryTable']);
|
||||
|
||||
function selectImageGallerySelect(imageUrl, fileId) {
|
||||
const D = props.gallerySelectDialog;
|
||||
D.selectedFileId = fileId;
|
||||
@@ -116,13 +113,13 @@
|
||||
r.onload = function () {
|
||||
const base64Body = btoa(r.result);
|
||||
vrcPlusImageRequest.uploadGalleryImage(base64Body).then((args) => {
|
||||
handleGalleryImageAdd(args);
|
||||
$message({
|
||||
message: t('message.gallery.uploaded'),
|
||||
type: 'success'
|
||||
});
|
||||
// API.$on('GALLERYIMAGE:ADD')
|
||||
if (Object.keys(props.galleryTable).length !== 0) {
|
||||
props.galleryTable.unshift(args.json);
|
||||
if (Object.keys(galleryTable.value).length !== 0) {
|
||||
galleryTable.value.unshift(args.json);
|
||||
}
|
||||
return args;
|
||||
});
|
||||
@@ -130,7 +127,4 @@
|
||||
r.readAsBinaryString(files[0]);
|
||||
clearFile();
|
||||
}
|
||||
function refreshGalleryTable() {
|
||||
emit('refreshGalleryTable');
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</el-popover>
|
||||
<div style="flex: 1; display: flex; align-items: center; margin-left: 15px">
|
||||
<div class="group-header" style="flex: 1">
|
||||
<span v-if="groupDialog.ref.ownerId === API.currentUser.id" style="margin-right: 5px">👑</span>
|
||||
<span v-if="groupDialog.ref.ownerId === currentUser.id" style="margin-right: 5px">👑</span>
|
||||
<span class="dialog-title" style="margin-right: 5px" v-text="groupDialog.ref.name"></span>
|
||||
<span
|
||||
class="group-discriminator x-grey"
|
||||
@@ -399,9 +399,9 @@
|
||||
</span>
|
||||
<div v-for="room in groupDialog.instances" :key="room.tag" style="width: 100%">
|
||||
<div style="margin: 5px 0">
|
||||
<location :location="room.tag" style="display: inline-block" />
|
||||
<Location :location="room.tag" style="display: inline-block" />
|
||||
<el-tooltip placement="top" content="Invite yourself" :disabled="hideTooltips">
|
||||
<invite-yourself :location="room.tag" style="margin-left: 5px" />
|
||||
<InviteYourself :location="room.tag" style="margin-left: 5px" />
|
||||
</el-tooltip>
|
||||
<el-tooltip placement="top" content="Refresh player count" :disabled="hideTooltips">
|
||||
<el-button
|
||||
@@ -411,12 +411,11 @@
|
||||
circle
|
||||
@click="refreshInstancePlayerCount(room.tag)" />
|
||||
</el-tooltip>
|
||||
<last-join :location="room.tag" :currentlocation="lastLocation.location" />
|
||||
<instance-info
|
||||
<LastJoin :location="room.tag" :currentlocation="lastLocation.location" />
|
||||
<InstanceInfo
|
||||
:location="room.tag"
|
||||
:instance="room.ref"
|
||||
:friendcount="room.friendCount"
|
||||
:updateelement="updateInstanceInfo" />
|
||||
:friendcount="room.friendCount" />
|
||||
</div>
|
||||
<div
|
||||
v-if="room.users.length"
|
||||
@@ -437,10 +436,10 @@
|
||||
v-text="user.displayName" />
|
||||
<span v-if="user.location === 'traveling'" class="extra">
|
||||
<i class="el-icon-loading" style="margin-right: 5px" />
|
||||
<timer :epoch="user.$travelingToTime" />
|
||||
<Timer :epoch="user.$travelingToTime" />
|
||||
</span>
|
||||
<span v-else class="extra">
|
||||
<timer :epoch="user.$location_at" />
|
||||
<Timer :epoch="user.$location_at" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -494,13 +493,14 @@
|
||||
<span>{{ t('dialog.group.posts.visibility') }}</span>
|
||||
<br />
|
||||
<template v-for="roleId in groupDialog.announcement.roleIds">
|
||||
<template v-for="role in groupDialog.ref.roles"
|
||||
><span
|
||||
v-if="role.id === roleId"
|
||||
:key="roleId + role.id"
|
||||
v-text="role.name"
|
||||
/></template>
|
||||
<span
|
||||
v-for="(role, rIndex) in groupDialog.ref.roles"
|
||||
v-if="role.id === roleId"
|
||||
:key="rIndex"
|
||||
v-text="role.name" />
|
||||
<span
|
||||
:key="rIndex"
|
||||
:key="roleId"
|
||||
v-if="
|
||||
groupDialog.announcement.roleIds.indexOf(roleId) <
|
||||
groupDialog.announcement.roleIds.length - 1
|
||||
@@ -511,18 +511,18 @@
|
||||
</template>
|
||||
<i class="el-icon-view" style="margin-right: 5px" />
|
||||
</el-tooltip>
|
||||
<display-name
|
||||
<DisplayName
|
||||
:userid="groupDialog.announcement.authorId"
|
||||
style="margin-right: 5px" />
|
||||
<span v-if="groupDialog.announcement.editorId" style="margin-right: 5px">
|
||||
({{ t('dialog.group.posts.edited_by') }}
|
||||
<display-name :userid="groupDialog.announcement.editorId" />)
|
||||
<DisplayName :userid="groupDialog.announcement.editorId" />)
|
||||
</span>
|
||||
<el-tooltip placement="bottom">
|
||||
<template #content>
|
||||
<span
|
||||
>{{ t('dialog.group.posts.created_at') }}
|
||||
{{ groupDialog.announcement.createdAt | formatDate('long') }}</span
|
||||
{{ formatDateFilter(groupDialog.announcement.createdAt, 'long') }}</span
|
||||
>
|
||||
<template
|
||||
v-if="
|
||||
@@ -532,11 +532,13 @@
|
||||
<br />
|
||||
<span
|
||||
>{{ t('dialog.group.posts.edited_at') }}
|
||||
{{ groupDialog.announcement.updatedAt | formatDate('long') }}</span
|
||||
{{
|
||||
formatDateFilter(groupDialog.announcement.updatedAt, 'long')
|
||||
}}</span
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
<timer :epoch="Date.parse(groupDialog.announcement.updatedAt)" />
|
||||
<Timer :epoch="Date.parse(groupDialog.announcement.updatedAt)" />
|
||||
</el-tooltip>
|
||||
<template v-if="hasGroupPermission(groupDialog.ref, 'group-announcement-manage')">
|
||||
<el-tooltip
|
||||
@@ -593,7 +595,7 @@
|
||||
<div class="x-friend-item" style="cursor: default">
|
||||
<div class="detail">
|
||||
<span class="name">{{ t('dialog.group.info.created_at') }}</span>
|
||||
<span class="extra">{{ groupDialog.ref.createdAt | formatDate('long') }}</span>
|
||||
<span class="extra">{{ formatDateFilter(groupDialog.ref.createdAt, 'long') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="x-friend-item" style="cursor: default">
|
||||
@@ -667,7 +669,7 @@
|
||||
<div class="detail">
|
||||
<span class="name">{{ t('dialog.group.info.joined_at') }}</span>
|
||||
<span class="extra">{{
|
||||
groupDialog.ref.myMember.joinedAt | formatDate('long')
|
||||
formatDateFilter(groupDialog.ref.myMember.joinedAt, 'long')
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -688,18 +690,18 @@
|
||||
<br />
|
||||
<span v-if="role.updatedAt"
|
||||
>{{ t('dialog.group.info.role_updated_at') }}
|
||||
{{ role.updatedAt | formatDate('long') }}</span
|
||||
{{ formatDateFilter(role.updatedAt, 'long') }}</span
|
||||
>
|
||||
<span v-else
|
||||
>{{ t('dialog.group.info.role_created_at') }}
|
||||
{{ role.createdAt | formatDate('long') }}</span
|
||||
{{ formatDateFilter(role.createdAt, 'long') }}</span
|
||||
>
|
||||
<br />
|
||||
<span>{{ t('dialog.group.info.role_permissions') }}</span>
|
||||
<br />
|
||||
<template v-for="(permission, pIndex) in role.permissions">
|
||||
<span :key="pIndex">{{ permission }}</span>
|
||||
<br />
|
||||
<br :key="pIndex + permission" />
|
||||
</template>
|
||||
</template>
|
||||
<span
|
||||
@@ -776,38 +778,40 @@
|
||||
<span>{{ t('dialog.group.posts.visibility') }}</span>
|
||||
<br />
|
||||
<template v-for="roleId in post.roleIds">
|
||||
<span
|
||||
v-for="(role, rIndex) in groupDialog.ref.roles"
|
||||
v-if="role.id === roleId"
|
||||
:key="rIndex"
|
||||
v-text="role.name" />
|
||||
<span v-if="post.roleIds.indexOf(roleId) < post.roleIds.length - 1"
|
||||
>, </span
|
||||
<template v-for="role in groupDialog.ref.roles"
|
||||
><span
|
||||
v-if="role.id === roleId"
|
||||
:key="role.id + roleId"
|
||||
v-text="role.name" />
|
||||
</template>
|
||||
<template
|
||||
v-if="post.roleIds.indexOf(roleId) < post.roleIds.length - 1"
|
||||
><span :key="roleId">, </span></template
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
<i class="el-icon-view" style="margin-right: 5px" />
|
||||
</el-tooltip>
|
||||
<display-name :userid="post.authorId" style="margin-right: 5px" />
|
||||
<DisplayName :userid="post.authorId" style="margin-right: 5px" />
|
||||
<span v-if="post.editorId" style="margin-right: 5px"
|
||||
>({{ t('dialog.group.posts.edited_by') }}
|
||||
<display-name :userid="post.editorId" />)</span
|
||||
<DisplayName :userid="post.editorId" />)</span
|
||||
>
|
||||
<el-tooltip placement="bottom">
|
||||
<template slot="content">
|
||||
<span
|
||||
>{{ t('dialog.group.posts.created_at') }}
|
||||
{{ post.createdAt | formatDate('long') }}</span
|
||||
{{ formatDateFilter(post.createdAt, 'long') }}</span
|
||||
>
|
||||
<template v-if="post.updatedAt !== post.createdAt">
|
||||
<br />
|
||||
<span
|
||||
>{{ t('dialog.group.posts.edited_at') }}
|
||||
{{ post.updatedAt | formatDate('long') }}</span
|
||||
{{ formatDateFilter(post.updatedAt, 'long') }}</span
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
<timer :epoch="Date.parse(post.updatedAt)" />
|
||||
<Timer :epoch="Date.parse(post.updatedAt)" />
|
||||
</el-tooltip>
|
||||
<template
|
||||
v-if="hasGroupPermission(groupDialog.ref, 'group-announcement-manage')">
|
||||
@@ -885,7 +889,7 @@
|
||||
@click.native.stop>
|
||||
<el-button size="mini">
|
||||
<span
|
||||
>{{ groupDialog.memberSortOrder.name }}
|
||||
>{{ t(groupDialog.memberSortOrder.name) }}
|
||||
<i class="el-icon-arrow-down el-icon--right"
|
||||
/></span>
|
||||
</el-button>
|
||||
@@ -894,7 +898,7 @@
|
||||
v-for="item in groupDialogSortingOptions"
|
||||
:key="item.name"
|
||||
@click.native="setGroupMemberSortOrder(item)"
|
||||
v-text="item.name" />
|
||||
v-text="t(item.name)" />
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<span style="margin-right: 5px">{{ t('dialog.group.members.filter') }}</span>
|
||||
@@ -906,7 +910,7 @@
|
||||
@click.native.stop>
|
||||
<el-button size="mini">
|
||||
<span
|
||||
>{{ groupDialog.memberFilter.name }}
|
||||
>{{ t(groupDialog.memberFilter.name) }}
|
||||
<i class="el-icon-arrow-down el-icon--right"
|
||||
/></span>
|
||||
</el-button>
|
||||
@@ -915,7 +919,7 @@
|
||||
v-for="item in groupDialogFilterOptions"
|
||||
:key="item.name"
|
||||
@click.native="setGroupMemberFilter(item)"
|
||||
v-text="item.name" />
|
||||
v-text="t(item.name)" />
|
||||
<el-dropdown-item
|
||||
v-for="item in groupDialog.ref.roles"
|
||||
v-if="!item.defaultRole"
|
||||
@@ -984,13 +988,13 @@
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-for="roleId in user.roleIds">
|
||||
<span
|
||||
v-for="(role, rIndex) in groupDialog.ref.roles"
|
||||
v-if="role.id === roleId"
|
||||
:key="rIndex"
|
||||
v-text="role.name" />
|
||||
<span v-if="user.roleIds.indexOf(roleId) < user.roleIds.length - 1"
|
||||
>, </span
|
||||
<template v-for="role in groupDialog.ref.roles"
|
||||
><span
|
||||
v-if="role.id === roleId"
|
||||
:key="role.id + roleId"
|
||||
v-text="role.name" /></template
|
||||
><template v-if="user.roleIds.indexOf(roleId) < user.roleIds.length - 1"
|
||||
><span :key="roleId">, </span></template
|
||||
>
|
||||
</template>
|
||||
</span>
|
||||
@@ -1048,19 +1052,18 @@
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-for="roleId in user.roleIds">
|
||||
<span
|
||||
v-for="(role, rIndex) in groupDialog.ref.roles"
|
||||
v-if="role.id === roleId"
|
||||
:key="rIndex"
|
||||
v-text="role.name" />
|
||||
<span v-if="user.roleIds.indexOf(roleId) < user.roleIds.length - 1"
|
||||
>, </span
|
||||
<template v-for="role in groupDialog.ref.roles"
|
||||
><span
|
||||
v-if="role.id === roleId"
|
||||
:key="roleId + role"
|
||||
v-text="role.name" /></template
|
||||
><template v-if="user.roleIds.indexOf(roleId) < user.roleIds.length - 1"
|
||||
><span :key="roleId"> </span></template
|
||||
>
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
<!--FIXME: div in ul-->
|
||||
<div
|
||||
v-if="!isGroupMembersDone"
|
||||
v-loading="isGroupMembersLoading"
|
||||
@@ -1150,108 +1153,75 @@
|
||||
<!--Nested-->
|
||||
<GroupPostEditDialog :dialog-data.sync="groupPostEditDialog" :selected-gallery-file="selectedGalleryFile" />
|
||||
<GroupMemberModerationDialog
|
||||
:group-dialog="groupDialog"
|
||||
:is-group-members-loading.sync="isGroupMembersLoading"
|
||||
:group-dialog-filter-options="groupDialogFilterOptions"
|
||||
:group-dialog-sorting-options="groupDialogSortingOptions"
|
||||
:random-user-colours="randomUserColours"
|
||||
:group-member-moderation="groupMemberModeration"
|
||||
@close-dialog="closeMemberModerationDialog"
|
||||
@group-members-search="groupMembersSearch"
|
||||
@load-all-group-members="loadAllGroupMembers"
|
||||
@set-group-member-filter="setGroupMemberFilter"
|
||||
@set-group-member-sort-order="setGroupMemberSortOrder" />
|
||||
<InviteGroupDialog
|
||||
:dialog-data.sync="inviteGroupDialog"
|
||||
:vip-friends="vipFriends"
|
||||
:online-friends="onlineFriends"
|
||||
:offline-friends="offlineFriends"
|
||||
:active-friends="activeFriends" />
|
||||
<InviteGroupDialog />
|
||||
</safe-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getCurrentInstance, inject, nextTick, reactive, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getCurrentInstance, nextTick, reactive, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import * as workerTimers from 'worker-timers';
|
||||
import { groupRequest } from '../../../api';
|
||||
import utils from '../../../classes/utils';
|
||||
import { hasGroupPermission } from '../../../composables/group/utils';
|
||||
import { refreshInstancePlayerCount } from '../../../composables/instance/utils';
|
||||
import { copyToClipboard, downloadAndSaveJson, getFaviconUrl } from '../../../composables/shared/utils';
|
||||
import { languageClass } from '../../../composables/user/utils';
|
||||
import Location from '../../Location.vue';
|
||||
import { $app } from '../../../app';
|
||||
import { groupDialogFilterOptions, groupDialogSortingOptions } from '../../../shared/constants';
|
||||
import {
|
||||
adjustDialogZ,
|
||||
buildTreeData,
|
||||
copyToClipboard,
|
||||
downloadAndSaveJson,
|
||||
getFaviconUrl,
|
||||
hasGroupPermission,
|
||||
languageClass,
|
||||
openExternalLink,
|
||||
refreshInstancePlayerCount,
|
||||
removeFromArray,
|
||||
userImage,
|
||||
userStatusClass,
|
||||
formatDateFilter
|
||||
} from '../../../shared/utils';
|
||||
import {
|
||||
useAppearanceSettingsStore,
|
||||
useGalleryStore,
|
||||
useGroupStore,
|
||||
useLocationStore,
|
||||
useUserStore
|
||||
} from '../../../stores';
|
||||
import InviteGroupDialog from '../InviteGroupDialog.vue';
|
||||
import GroupMemberModerationDialog from './GroupMemberModerationDialog.vue';
|
||||
import GroupPostEditDialog from './GroupPostEditDialog.vue';
|
||||
|
||||
const API = inject('API');
|
||||
const showFullscreenImageDialog = inject('showFullscreenImageDialog');
|
||||
const showUserDialog = inject('showUserDialog');
|
||||
const userStatusClass = inject('userStatusClass');
|
||||
const userImage = inject('userImage');
|
||||
const openExternalLink = inject('openExternalLink');
|
||||
const adjustDialogZ = inject('adjustDialogZ');
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { hideTooltips } = storeToRefs(useAppearanceSettingsStore());
|
||||
const { showUserDialog } = useUserStore();
|
||||
const { currentUser } = storeToRefs(useUserStore());
|
||||
const { groupDialog, inviteGroupDialog } = storeToRefs(useGroupStore());
|
||||
const {
|
||||
getGroupDialogGroup,
|
||||
updateGroupPostSearch,
|
||||
showGroupDialog,
|
||||
leaveGroupPrompt,
|
||||
setGroupVisibility,
|
||||
applyGroupMember,
|
||||
handleGroupMember,
|
||||
handleGroupMemberProps
|
||||
} = useGroupStore();
|
||||
|
||||
const { lastLocation } = storeToRefs(useLocationStore());
|
||||
const { showFullscreenImageDialog } = useGalleryStore();
|
||||
|
||||
const instance = getCurrentInstance();
|
||||
const $confirm = instance.proxy.$confirm;
|
||||
const $message = instance.proxy.$message;
|
||||
|
||||
const props = defineProps({
|
||||
groupDialog: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
hideTooltips: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
lastLocation: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
updateInstanceInfo: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
groupDialogSortingOptions: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
groupDialogFilterOptions: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
randomUserColours: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
vipFriends: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
onlineFriends: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
offlineFriends: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
activeFriends: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
'update:group-dialog',
|
||||
'groupDialogCommand',
|
||||
'getGroupDialogGroup',
|
||||
'updateGroupPostSearch'
|
||||
]);
|
||||
|
||||
const groupDialogRef = ref(null);
|
||||
const isGroupMembersDone = ref(false);
|
||||
const isGroupMembersLoading = ref(false);
|
||||
@@ -1283,20 +1253,10 @@
|
||||
auditLogTypes: []
|
||||
});
|
||||
|
||||
const inviteGroupDialog = ref({
|
||||
visible: false,
|
||||
loading: false,
|
||||
groupId: '',
|
||||
groupName: '',
|
||||
userId: '',
|
||||
userIds: [],
|
||||
userObject: {}
|
||||
});
|
||||
|
||||
let loadMoreGroupMembersParams = {};
|
||||
|
||||
watch(
|
||||
() => props.groupDialog.loading,
|
||||
() => groupDialog.value.loading,
|
||||
(val) => {
|
||||
if (val) {
|
||||
nextTick(() => adjustDialogZ(groupDialogRef.value.$el));
|
||||
@@ -1305,7 +1265,7 @@
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.groupDialog.isGetGroupDialogGroupLoading,
|
||||
() => groupDialog.value.isGetGroupDialogGroupLoading,
|
||||
(val) => {
|
||||
if (val) {
|
||||
getCurrentTabData();
|
||||
@@ -1314,14 +1274,9 @@
|
||||
);
|
||||
|
||||
function showInviteGroupDialog(groupId, userId) {
|
||||
const D = inviteGroupDialog.value;
|
||||
D.userIds = '';
|
||||
D.groups = [];
|
||||
D.groupId = groupId;
|
||||
D.groupName = groupId;
|
||||
D.userId = userId;
|
||||
D.userObject = {};
|
||||
D.visible = true;
|
||||
inviteGroupDialog.value.groupId = groupId;
|
||||
inviteGroupDialog.value.userId = userId;
|
||||
inviteGroupDialog.value.visible = true;
|
||||
}
|
||||
|
||||
function setGroupRepresentation(groupId) {
|
||||
@@ -1360,7 +1315,7 @@
|
||||
}
|
||||
|
||||
function groupMembersSearchDebounce() {
|
||||
const D = props.groupDialog;
|
||||
const D = groupDialog.value;
|
||||
const search = D.memberSearch;
|
||||
D.memberSearchResults = [];
|
||||
if (!search || search.length < 3) {
|
||||
@@ -1375,16 +1330,14 @@
|
||||
offset: 0
|
||||
})
|
||||
.then((args) => {
|
||||
// API.$on('GROUP:MEMBERS:SEARCH', function (args) {
|
||||
for (const json of args.json.results) {
|
||||
API.$emit('GROUP:MEMBER', {
|
||||
handleGroupMember({
|
||||
json,
|
||||
params: {
|
||||
groupId: args.params.groupId
|
||||
}
|
||||
});
|
||||
}
|
||||
// });
|
||||
if (D.id === args.params.groupId) {
|
||||
D.memberSearchResults = args.json.results;
|
||||
}
|
||||
@@ -1400,11 +1353,10 @@
|
||||
isRepresenting: isSet
|
||||
})
|
||||
.then((args) => {
|
||||
// API.$on('GROUP:SETREPRESENTATION', function (args) {
|
||||
if (props.groupDialog.visible && props.groupDialog.id === groupId) {
|
||||
if (groupDialog.value.visible && groupDialog.value.id === args.groupId) {
|
||||
updateGroupDialogData({
|
||||
...props.groupDialog,
|
||||
ref: { ...props.groupDialog.ref, isRepresenting: args.params.isRepresenting }
|
||||
...groupDialog.value,
|
||||
ref: { ...groupDialog.value.ref, isRepresenting: args.params.isRepresenting }
|
||||
});
|
||||
getGroupDialogGroup(groupId);
|
||||
}
|
||||
@@ -1417,11 +1369,9 @@
|
||||
groupId: id
|
||||
})
|
||||
.then((args) => {
|
||||
// API.$on('GROUP:CANCELJOINREQUEST', function (args) {
|
||||
if (props.groupDialog.visible && props.groupDialog.id === id) {
|
||||
if (groupDialog.value.visible && groupDialog.value.id === id) {
|
||||
getGroupDialogGroup(id);
|
||||
}
|
||||
// });
|
||||
});
|
||||
}
|
||||
function confirmDeleteGroupPost(post) {
|
||||
@@ -1437,8 +1387,7 @@
|
||||
postId: post.id
|
||||
})
|
||||
.then((args) => {
|
||||
// API.$on('GROUP:POST:DELETE', function (args) {
|
||||
const D = props.groupDialog;
|
||||
const D = groupDialog.value;
|
||||
if (D.id !== args.params.groupId) {
|
||||
return;
|
||||
}
|
||||
@@ -1447,7 +1396,7 @@
|
||||
// remove existing post
|
||||
for (const item of D.posts) {
|
||||
if (item.id === postId) {
|
||||
utils.removeFromArray(D.posts, item);
|
||||
removeFromArray(D.posts, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1460,7 +1409,6 @@
|
||||
}
|
||||
}
|
||||
updateGroupPostSearch();
|
||||
// });
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1480,30 +1428,113 @@
|
||||
}
|
||||
|
||||
function groupDialogCommand(command) {
|
||||
const D = props.groupDialog;
|
||||
const D = groupDialog.value;
|
||||
if (D.visible === false) {
|
||||
return;
|
||||
}
|
||||
switch (command) {
|
||||
case 'Share':
|
||||
copyToClipboard(props.groupDialog.ref.$url);
|
||||
copyToClipboard(groupDialog.value.ref.$url);
|
||||
break;
|
||||
case 'Create Post':
|
||||
showGroupPostEditDialog(props.groupDialog.id, null);
|
||||
showGroupPostEditDialog(groupDialog.value.id, null);
|
||||
break;
|
||||
case 'Moderation Tools':
|
||||
showGroupMemberModerationDialog(props.groupDialog.id);
|
||||
showGroupMemberModerationDialog(groupDialog.value.id);
|
||||
break;
|
||||
case 'Invite To Group':
|
||||
showInviteGroupDialog(D.id, '');
|
||||
break;
|
||||
default:
|
||||
emit('groupDialogCommand', command);
|
||||
case 'Refresh':
|
||||
showGroupDialog(D.id);
|
||||
break;
|
||||
case 'Leave Group':
|
||||
leaveGroupPrompt(D.id);
|
||||
break;
|
||||
case 'Block Group':
|
||||
blockGroup(D.id);
|
||||
break;
|
||||
case 'Unblock Group':
|
||||
unblockGroup(D.id);
|
||||
break;
|
||||
case 'Visibility Everyone':
|
||||
setGroupVisibility(D.id, 'visible');
|
||||
break;
|
||||
case 'Visibility Friends':
|
||||
setGroupVisibility(D.id, 'friends');
|
||||
break;
|
||||
case 'Visibility Hidden':
|
||||
setGroupVisibility(D.id, 'hidden');
|
||||
break;
|
||||
case 'Subscribe To Announcements':
|
||||
setGroupSubscription(D.id, true);
|
||||
break;
|
||||
case 'Unsubscribe To Announcements':
|
||||
setGroupSubscription(D.id, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function setGroupSubscription(groupId, subscribe) {
|
||||
return groupRequest
|
||||
.setGroupMemberProps(currentUser.value.id, groupId, {
|
||||
isSubscribedToAnnouncements: subscribe
|
||||
})
|
||||
.then((args) => {
|
||||
handleGroupMemberProps(args);
|
||||
$app.$message({
|
||||
message: 'Group subscription updated',
|
||||
type: 'success'
|
||||
});
|
||||
return args;
|
||||
});
|
||||
}
|
||||
|
||||
function blockGroup(groupId) {
|
||||
$app.$confirm('Are you sure you want to block this group?', 'Confirm', {
|
||||
confirmButtonText: 'Confirm',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'info',
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
groupRequest
|
||||
.blockGroup({
|
||||
groupId
|
||||
})
|
||||
.then((args) => {
|
||||
if (groupDialog.value.visible && groupDialog.value.id === args.params.groupId) {
|
||||
showGroupDialog(args.params.groupId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function unblockGroup(groupId) {
|
||||
$app.$confirm('Are you sure you want to unblock this group?', 'Confirm', {
|
||||
confirmButtonText: 'Confirm',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'info',
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
groupRequest
|
||||
.unblockGroup({
|
||||
groupId,
|
||||
userId: currentUser.value.id
|
||||
})
|
||||
.then((args) => {
|
||||
if (groupDialog.value.visible && groupDialog.value.id === args.params.groupId) {
|
||||
showGroupDialog(args.params.groupId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showGroupMemberModerationDialog(groupId) {
|
||||
if (groupId !== props.groupDialog.id) {
|
||||
if (groupId !== groupDialog.value.id) {
|
||||
return;
|
||||
}
|
||||
const D = groupMemberModeration;
|
||||
@@ -1511,16 +1542,14 @@
|
||||
|
||||
D.groupRef = {};
|
||||
D.auditLogTypes = [];
|
||||
API.getCachedGroup({ groupId }).then((args) => {
|
||||
groupRequest.getCachedGroup({ groupId }).then((args) => {
|
||||
D.groupRef = args.ref;
|
||||
if (hasGroupPermission(D.groupRef, 'group-audit-view')) {
|
||||
groupRequest.getGroupAuditLogTypes({ groupId }).then((args) => {
|
||||
// API.$on('GROUP:AUDITLOGTYPES', function (args) {
|
||||
if (groupMemberModeration.id !== args.params.groupId) {
|
||||
return;
|
||||
}
|
||||
groupMemberModeration.auditLogTypes = args.json;
|
||||
// });
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1535,16 +1564,14 @@
|
||||
groupId: id
|
||||
})
|
||||
.then((args) => {
|
||||
// API.$on('GROUP:JOIN', function (args) {
|
||||
if (props.groupDialog.visible && props.groupDialog.id === id) {
|
||||
if (groupDialog.value.visible && groupDialog.value.id === id) {
|
||||
updateGroupDialogData({
|
||||
...props.groupDialog,
|
||||
...groupDialog.value,
|
||||
inGroup: args.json.membershipStatus === 'member'
|
||||
});
|
||||
// props.groupDialog.inGroup = args.json.membershipStatus === 'member';
|
||||
// groupDialog.value.inGroup = json.membershipStatus === 'member';
|
||||
getGroupDialogGroup(id);
|
||||
}
|
||||
// });
|
||||
if (args.json.membershipStatus === 'member') {
|
||||
$message({
|
||||
message: 'Group joined',
|
||||
@@ -1595,14 +1622,14 @@
|
||||
selectedImageUrl: post.imageUrl
|
||||
};
|
||||
}
|
||||
API.getCachedGroup({ groupId }).then((args) => {
|
||||
groupRequest.getCachedGroup({ groupId }).then((args) => {
|
||||
D.groupRef = args.ref;
|
||||
});
|
||||
D.visible = true;
|
||||
}
|
||||
|
||||
async function getGroupDialogGroupMembers() {
|
||||
const D = props.groupDialog;
|
||||
const D = groupDialog.value;
|
||||
D.members = [];
|
||||
isGroupMembersDone.value = false;
|
||||
loadMoreGroupMembersParams = {
|
||||
@@ -1620,12 +1647,12 @@
|
||||
await groupRequest
|
||||
.getGroupMember({
|
||||
groupId: D.id,
|
||||
userId: API.currentUser.id
|
||||
userId: currentUser.value.id
|
||||
})
|
||||
.then((args) => {
|
||||
args.ref = API.applyGroupMember(args.json);
|
||||
args.ref = applyGroupMember(args.json);
|
||||
if (args.json) {
|
||||
args.json.user = API.currentUser;
|
||||
args.json.user = currentUser.value;
|
||||
if (D.memberFilter.id === null) {
|
||||
// when flitered by role don't include self
|
||||
D.members.push(args.json);
|
||||
@@ -1641,7 +1668,7 @@
|
||||
if (isGroupMembersDone.value || isGroupMembersLoading.value) {
|
||||
return;
|
||||
}
|
||||
const D = props.groupDialog;
|
||||
const D = groupDialog.value;
|
||||
const params = loadMoreGroupMembersParams;
|
||||
D.memberSearch = '';
|
||||
isGroupMembersLoading.value = true;
|
||||
@@ -1651,10 +1678,18 @@
|
||||
isGroupMembersLoading.value = false;
|
||||
})
|
||||
.then((args) => {
|
||||
for (const json of args.json) {
|
||||
handleGroupMember({
|
||||
json,
|
||||
params: {
|
||||
groupId: args.params.groupId
|
||||
}
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < args.json.length; i++) {
|
||||
const member = args.json[i];
|
||||
if (member.userId === API.currentUser.id) {
|
||||
if (D.members.length > 0 && D.members[0].userId === API.currentUser.id) {
|
||||
if (member.userId === currentUser.value.id) {
|
||||
if (D.members.length > 0 && D.members[0].userId === currentUser.value.id) {
|
||||
// remove duplicate and keep sort order
|
||||
D.members.splice(0, 1);
|
||||
}
|
||||
@@ -1685,12 +1720,12 @@
|
||||
}
|
||||
|
||||
async function getGroupGalleries() {
|
||||
updateGroupDialogData({ ...props.groupDialog, galleries: {} });
|
||||
updateGroupDialogData({ ...groupDialog.value, galleries: {} });
|
||||
groupDialogGalleryCurrentName.value = '0';
|
||||
isGroupGalleryLoading.value = true;
|
||||
for (let i = 0; i < props.groupDialog.ref.galleries.length; i++) {
|
||||
const gallery = props.groupDialog.ref.galleries[i];
|
||||
await getGroupGallery(props.groupDialog.id, gallery.id);
|
||||
for (let i = 0; i < groupDialog.value.ref.galleries.length; i++) {
|
||||
const gallery = groupDialog.value.ref.galleries[i];
|
||||
await getGroupGallery(groupDialog.value.id, gallery.id);
|
||||
}
|
||||
isGroupGalleryLoading.value = false;
|
||||
}
|
||||
@@ -1707,16 +1742,14 @@
|
||||
for (let i = 0; i < count; i++) {
|
||||
const args = await groupRequest.getGroupGallery(params);
|
||||
if (args) {
|
||||
// API.$on('GROUP:GALLERY', function (args) {
|
||||
for (const json of args.json) {
|
||||
if (props.groupDialog.id === json.groupId) {
|
||||
if (!props.groupDialog.galleries[json.galleryId]) {
|
||||
props.groupDialog.galleries[json.galleryId] = [];
|
||||
if (groupDialog.value.id === json.groupId) {
|
||||
if (!groupDialog.value.galleries[json.galleryId]) {
|
||||
groupDialog.value.galleries[json.galleryId] = [];
|
||||
}
|
||||
props.groupDialog.galleries[json.galleryId].push(json);
|
||||
groupDialog.value.galleries[json.galleryId].push(json);
|
||||
}
|
||||
}
|
||||
// });
|
||||
}
|
||||
params.offset += 100;
|
||||
if (args.json.length < 100) {
|
||||
@@ -1729,8 +1762,8 @@
|
||||
}
|
||||
|
||||
function refreshGroupDialogTreeData() {
|
||||
const D = props.groupDialog;
|
||||
const treeData = utils.buildTreeData({
|
||||
const D = groupDialog.value;
|
||||
const treeData = buildTreeData({
|
||||
group: D.ref,
|
||||
posts: D.posts,
|
||||
instances: D.instances,
|
||||
@@ -1738,7 +1771,7 @@
|
||||
galleries: D.galleries
|
||||
});
|
||||
updateGroupDialogData({
|
||||
...props.groupDialog,
|
||||
...groupDialog.value,
|
||||
treeData
|
||||
});
|
||||
}
|
||||
@@ -1748,19 +1781,19 @@
|
||||
return;
|
||||
}
|
||||
await getGroupDialogGroupMembers();
|
||||
while (props.groupDialog.visible && !isGroupMembersDone.value) {
|
||||
while (groupDialog.value.visible && !isGroupMembersDone.value) {
|
||||
isGroupMembersLoading.value = true;
|
||||
await new Promise((resolve) => {
|
||||
workerTimers.setTimeout(resolve, 1000);
|
||||
});
|
||||
isGroupMembersLoading.value = false;
|
||||
await this.loadMoreGroupMembers();
|
||||
await loadMoreGroupMembers();
|
||||
}
|
||||
}
|
||||
|
||||
async function setGroupMemberSortOrder(sortOrder) {
|
||||
const D = props.groupDialog;
|
||||
if (D.memberSortOrder === sortOrder) {
|
||||
const D = groupDialog.value;
|
||||
if (D.memberSortOrder.value === sortOrder) {
|
||||
return;
|
||||
}
|
||||
D.memberSortOrder = sortOrder;
|
||||
@@ -1768,8 +1801,8 @@
|
||||
}
|
||||
|
||||
async function setGroupMemberFilter(filter) {
|
||||
const D = props.groupDialog;
|
||||
if (D.memberFilter === filter) {
|
||||
const D = groupDialog.value;
|
||||
if (D.memberFilter.value === filter) {
|
||||
return;
|
||||
}
|
||||
D.memberFilter = filter;
|
||||
@@ -1777,13 +1810,9 @@
|
||||
}
|
||||
|
||||
function updateGroupDialogData(obj) {
|
||||
// Be careful with the deep merge
|
||||
emit('update:group-dialog', obj);
|
||||
}
|
||||
function getGroupDialogGroup(groupId) {
|
||||
emit('getGroupDialogGroup', groupId);
|
||||
}
|
||||
function updateGroupPostSearch() {
|
||||
emit('updateGroupPostSearch');
|
||||
groupDialog.value = {
|
||||
...groupDialog.value,
|
||||
...obj
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
icon="el-icon-refresh"
|
||||
:loading="isGroupMembersLoading"
|
||||
circle
|
||||
@click="loadAllGroupMembers"></el-button>
|
||||
@click="loadAllGroupMembers" />
|
||||
<span style="font-size: 14px; margin-left: 5px; margin-right: 5px">
|
||||
{{ groupMemberModerationTable.data.length }}/{{
|
||||
groupMemberModeration.groupRef.memberCount
|
||||
@@ -40,7 +40,7 @@
|
||||
@click.native.stop>
|
||||
<el-button size="mini">
|
||||
<span
|
||||
>{{ groupDialog.memberSortOrder.name }}
|
||||
>{{ t(groupDialog.memberSortOrder.name) }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i
|
||||
></span>
|
||||
</el-button>
|
||||
@@ -49,7 +49,7 @@
|
||||
v-for="item in groupDialogSortingOptions"
|
||||
:key="item.name"
|
||||
@click.native="setGroupMemberSortOrder(item)">
|
||||
{{ item.name }}
|
||||
{{ t(item.name) }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
@@ -68,7 +68,7 @@
|
||||
@click.native.stop>
|
||||
<el-button size="mini">
|
||||
<span
|
||||
>{{ groupDialog.memberFilter.name }}
|
||||
>{{ t(groupDialog.memberFilter.name) }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i
|
||||
></span>
|
||||
</el-button>
|
||||
@@ -77,7 +77,7 @@
|
||||
v-for="item in groupDialogFilterOptions"
|
||||
:key="item.name"
|
||||
@click.native="setGroupMemberFilter(item)"
|
||||
v-text="item.name"></el-dropdown-item>
|
||||
v-text="t(item.name)"></el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-for="item in groupDialog.ref.roles"
|
||||
v-if="!item.defaultRole"
|
||||
@@ -147,12 +147,11 @@
|
||||
<el-table-column :label="t('dialog.group_member_moderation.roles')" prop="roleIds" sortable>
|
||||
<template slot-scope="scope">
|
||||
<template v-for="(roleId, index) in scope.row.roleIds">
|
||||
<span
|
||||
v-for="(role, rIndex) in groupMemberModeration.groupRef.roles"
|
||||
v-if="role?.id === roleId"
|
||||
:key="rIndex"
|
||||
>{{ role.name
|
||||
}}<span v-if="index < scope.row.roleIds.length - 1">, </span></span
|
||||
<template v-for="(role, rIndex) in groupMemberModeration.groupRef.roles">
|
||||
<span v-if="role?.id === roleId" :key="roleId + rIndex"
|
||||
>{{ role.name
|
||||
}}<span v-if="index < scope.row.roleIds.length - 1">, </span></span
|
||||
></template
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
@@ -171,7 +170,7 @@
|
||||
prop="joinedAt"
|
||||
sortable>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.joinedAt | formatDate('long') }}</span>
|
||||
<span>{{ formatDateFilter(scope.row.joinedAt, 'long') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
@@ -284,7 +283,7 @@
|
||||
prop="joinedAt"
|
||||
sortable>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.joinedAt | formatDate('long') }}</span>
|
||||
<span>{{ formatDateFilter(scope.row.joinedAt, 'long') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
@@ -293,7 +292,7 @@
|
||||
prop="bannedAt"
|
||||
sortable>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.bannedAt | formatDate('long') }}</span>
|
||||
<span>{{ formatDateFilter(scope.row.bannedAt, 'long') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</data-tables>
|
||||
@@ -629,7 +628,7 @@
|
||||
prop="created_at"
|
||||
sortable>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.created_at | formatDate('long') }}</span>
|
||||
<span>{{ formatDateFilter(scope.row.created_at, 'long') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
@@ -656,7 +655,7 @@
|
||||
:label="t('dialog.group_member_moderation.description')"
|
||||
prop="description">
|
||||
<template slot-scope="scope">
|
||||
<location
|
||||
<Location
|
||||
v-if="scope.row?.targetId.startsWith('wrld_')"
|
||||
:location="scope.row.targetId" />
|
||||
<span v-text="scope.row.description"></span>
|
||||
@@ -810,45 +809,165 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Location from '../../Location.vue';
|
||||
import { getCurrentInstance, inject, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getCurrentInstance, reactive, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import { groupRequest, userRequest } from '../../../api';
|
||||
import { useModerationTable, useSelectedUsers } from '../../../composables/group/useGroupMemberModeration';
|
||||
import { hasGroupPermission } from '../../../composables/group/utils';
|
||||
import { groupDialogFilterOptions, groupDialogSortingOptions } from '../../../shared/constants';
|
||||
import { hasGroupPermission, userImage, userImageFull, formatDateFilter } from '../../../shared/utils';
|
||||
import { useAppearanceSettingsStore, useGalleryStore, useGroupStore, useUserStore } from '../../../stores';
|
||||
import GroupMemberModerationExportDialog from './GroupMemberModerationExportDialog.vue';
|
||||
|
||||
const API = inject('API');
|
||||
const showUserDialog = inject('showUserDialog');
|
||||
const userImage = inject('userImage');
|
||||
const userImageFull = inject('userImageFull');
|
||||
const showFullscreenImageDialog = inject('showFullscreenImageDialog');
|
||||
|
||||
const { randomUserColours } = storeToRefs(useAppearanceSettingsStore());
|
||||
const { showUserDialog } = useUserStore();
|
||||
const { currentUser } = storeToRefs(useUserStore());
|
||||
const { groupDialog } = storeToRefs(useGroupStore());
|
||||
const { applyGroupMember, handleGroupMemberProps } = useGroupStore();
|
||||
const { showFullscreenImageDialog } = useGalleryStore();
|
||||
const { t } = useI18n();
|
||||
const instance = getCurrentInstance();
|
||||
const $message = instance.proxy.$message;
|
||||
|
||||
const selectedUsers = reactive({});
|
||||
const selectedUsersArray = ref([]);
|
||||
|
||||
function setSelectedUsers(usersId, user) {
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
selectedUsers[usersId] = user;
|
||||
selectedUsersArray.value = Object.values(selectedUsers);
|
||||
}
|
||||
|
||||
function deselectedUsers(userId, isAll = false) {
|
||||
if (isAll) {
|
||||
for (const id in selectedUsers) {
|
||||
if (Object.prototype.hasOwnProperty.call(selectedUsers, id)) {
|
||||
delete selectedUsers[id];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Object.prototype.hasOwnProperty.call(selectedUsers, userId)) {
|
||||
delete selectedUsers[userId];
|
||||
}
|
||||
}
|
||||
selectedUsersArray.value = Object.values(selectedUsers);
|
||||
}
|
||||
|
||||
function groupMemberModerationTableSelectionChange(row) {
|
||||
if (row.$selected && !selectedUsers[row.userId]) {
|
||||
setSelectedUsers(row.userId, row);
|
||||
} else if (!row.$selected && selectedUsers[row.userId]) {
|
||||
deselectedUsers(row.userId);
|
||||
}
|
||||
}
|
||||
|
||||
const groupInvitesModerationTable = reactive({
|
||||
data: [],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
const groupJoinRequestsModerationTable = reactive({
|
||||
data: [],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
const groupBlockedModerationTable = reactive({
|
||||
data: [],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
const groupLogsModerationTable = reactive({
|
||||
data: [],
|
||||
filters: [{ prop: ['description'], value: '' }],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
const groupBansModerationTable = reactive({
|
||||
data: [],
|
||||
filters: [{ prop: ['$displayName'], value: '' }],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
const groupMemberModerationTable = reactive({
|
||||
data: [],
|
||||
tableProps: { stripe: true, size: 'mini' },
|
||||
pageSize: 15,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 20, 25, 50, 100]
|
||||
}
|
||||
});
|
||||
|
||||
async function initializePageSize() {
|
||||
try {
|
||||
const { tablePageSize } = storeToRefs(useAppearanceSettingsStore());
|
||||
|
||||
groupMemberModerationTable.pageSize = tablePageSize.value;
|
||||
groupBansModerationTable.pageSize = tablePageSize.value;
|
||||
groupLogsModerationTable.pageSize = tablePageSize.value;
|
||||
groupInvitesModerationTable.pageSize = tablePageSize.value;
|
||||
groupJoinRequestsModerationTable.pageSize = tablePageSize.value;
|
||||
groupBlockedModerationTable.pageSize = tablePageSize.value;
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize table page size:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function deselectGroupMember(userId) {
|
||||
const deselectInTable = (tableData) => {
|
||||
if (userId) {
|
||||
const row = tableData.find((item) => item.userId === userId);
|
||||
if (row) {
|
||||
row.$selected = false;
|
||||
}
|
||||
} else {
|
||||
tableData.forEach((row) => {
|
||||
if (row.$selected) {
|
||||
row.$selected = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
deselectInTable(groupMemberModerationTable.data);
|
||||
deselectInTable(groupBansModerationTable.data);
|
||||
deselectInTable(groupInvitesModerationTable.data);
|
||||
deselectInTable(groupJoinRequestsModerationTable.data);
|
||||
deselectInTable(groupBlockedModerationTable.data);
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
isGroupMembersLoading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
groupDialog: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
groupDialogSortingOptions: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
groupDialogFilterOptions: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
randomUserColours: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
groupMemberModeration: {
|
||||
type: Object,
|
||||
required: true
|
||||
@@ -864,25 +983,6 @@
|
||||
'group-members-search'
|
||||
]);
|
||||
|
||||
const {
|
||||
groupInvitesModerationTable,
|
||||
groupJoinRequestsModerationTable,
|
||||
groupBlockedModerationTable,
|
||||
groupLogsModerationTable,
|
||||
groupBansModerationTable,
|
||||
groupMemberModerationTable,
|
||||
initializePageSize,
|
||||
deselectGroupMember
|
||||
} = useModerationTable();
|
||||
|
||||
const {
|
||||
selectedUsers,
|
||||
selectedUsersArray,
|
||||
groupMemberModerationTableSelectionChange,
|
||||
deselectedUsers,
|
||||
setSelectedUsers
|
||||
} = useSelectedUsers();
|
||||
|
||||
const selectUserId = ref('');
|
||||
const progressCurrent = ref(0);
|
||||
const progressTotal = ref(0);
|
||||
@@ -895,7 +995,7 @@
|
||||
() => props.groupMemberModeration.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
if (props.groupMemberModeration.id !== props.groupDialog.id) {
|
||||
if (props.groupMemberModeration.id !== groupDialog.value.id) {
|
||||
return;
|
||||
}
|
||||
groupMemberModerationTable.data = [];
|
||||
@@ -905,6 +1005,7 @@
|
||||
groupBlockedModerationTable.data = [];
|
||||
groupLogsModerationTable.data = [];
|
||||
Object.assign(selectedUsers, {});
|
||||
selectedUsersArray.value = [];
|
||||
selectUserId.value = '';
|
||||
selectedRoles.value = [];
|
||||
note.value = '';
|
||||
@@ -913,7 +1014,7 @@
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.groupDialog.members,
|
||||
() => groupDialog.value.members,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
setGroupMemberModerationTable(newVal);
|
||||
@@ -923,7 +1024,7 @@
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.groupDialog.memberSearchResults,
|
||||
() => groupDialog.value.memberSearchResults,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
setGroupMemberModerationTable(newVal);
|
||||
@@ -965,9 +1066,8 @@
|
||||
}
|
||||
|
||||
function handleGroupMemberRoleChange(args) {
|
||||
// 'GROUP:MEMBER:ROLE:CHANGE'
|
||||
if (props.groupDialog.id === args.params.groupId) {
|
||||
props.groupDialog.members.forEach((member) => {
|
||||
if (groupDialog.value.id === args.params.groupId) {
|
||||
groupDialog.value.members.forEach((member) => {
|
||||
if (member.userId === args.params.userId) {
|
||||
member.roleIds = args.json;
|
||||
return true;
|
||||
@@ -988,7 +1088,7 @@
|
||||
}
|
||||
const user = users[i];
|
||||
progressCurrent.value = i + 1;
|
||||
if (user.userId === API.currentUser.id) {
|
||||
if (user.userId === currentUser.value.id) {
|
||||
continue;
|
||||
}
|
||||
console.log(`Deleting group invite ${user.userId} ${i + 1}/${memberCount}`);
|
||||
@@ -1014,7 +1114,7 @@
|
||||
}
|
||||
progressCurrent.value = 0;
|
||||
progressTotal.value = 0;
|
||||
getAllGroupInvites(D.id, groupInvitesModerationTable);
|
||||
getAllGroupInvites(D.id);
|
||||
}
|
||||
|
||||
function selectAllGroupMembers() {
|
||||
@@ -1038,7 +1138,7 @@
|
||||
continue;
|
||||
}
|
||||
args.json.forEach((json) => {
|
||||
const ref = API.applyGroupMember(json);
|
||||
const ref = applyGroupMember(json);
|
||||
fetchedBans.push(ref);
|
||||
});
|
||||
if (args.json.length < params.n) {
|
||||
@@ -1076,7 +1176,7 @@
|
||||
if (!progressTotal.value) break;
|
||||
const user = users[i];
|
||||
progressCurrent.value = i + 1;
|
||||
if (user.userId === API.currentUser.id) continue;
|
||||
if (user.userId === currentUser.value.id) continue;
|
||||
console.log(`Banning ${user.userId} ${i + 1}/${memberCount}`);
|
||||
try {
|
||||
await groupRequest.banGroupMember({ groupId: D.id, userId: user.userId });
|
||||
@@ -1105,7 +1205,7 @@
|
||||
if (!progressTotal.value) break;
|
||||
const user = users[i];
|
||||
progressCurrent.value = i + 1;
|
||||
if (user.userId === API.currentUser.id) continue;
|
||||
if (user.userId === currentUser.value.id) continue;
|
||||
console.log(`Unbanning ${user.userId} ${i + 1}/${memberCount}`);
|
||||
try {
|
||||
await groupRequest.unbanGroupMember({ groupId: D.id, userId: user.userId });
|
||||
@@ -1138,7 +1238,7 @@
|
||||
if (!progressTotal.value) break;
|
||||
const user = users[i];
|
||||
progressCurrent.value = i + 1;
|
||||
if (user.userId === API.currentUser.id) continue;
|
||||
if (user.userId === currentUser.value.id) continue;
|
||||
|
||||
console.log(`Kicking ${user.userId} ${i + 1}/${memberCount}`);
|
||||
try {
|
||||
@@ -1158,6 +1258,7 @@
|
||||
progressCurrent.value = 0;
|
||||
progressTotal.value = 0;
|
||||
deselectedUsers(null, true);
|
||||
loadAllGroupMembers();
|
||||
}
|
||||
|
||||
async function groupMembersSaveNote() {
|
||||
@@ -1176,7 +1277,8 @@
|
||||
}
|
||||
console.log(`Setting note ${noteToSave} for ${user.userId} ${i + 1}/${memberCount}`);
|
||||
try {
|
||||
await groupRequest.setGroupMemberProps(user.userId, D.id, { managerNotes: noteToSave });
|
||||
const args = await groupRequest.setGroupMemberProps(user.userId, D.id, { managerNotes: noteToSave });
|
||||
handleGroupMemberProps(args);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
$message({
|
||||
@@ -1334,7 +1436,7 @@
|
||||
let member = {};
|
||||
const memberArgs = await groupRequest.getGroupMember({ groupId: D.id, userId });
|
||||
if (memberArgs && memberArgs.json) {
|
||||
member = API.applyGroupMember(memberArgs.json);
|
||||
member = applyGroupMember(memberArgs.json);
|
||||
}
|
||||
if (member && member.user) {
|
||||
setSelectedUsers(member.userId, member);
|
||||
@@ -1400,7 +1502,7 @@
|
||||
const user = users[i];
|
||||
progressCurrent.value = i + 1;
|
||||
|
||||
if (user.userId === API.currentUser.id) {
|
||||
if (user.userId === currentUser.value.id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1424,7 +1526,7 @@
|
||||
}
|
||||
progressCurrent.value = 0;
|
||||
progressTotal.value = 0;
|
||||
getAllGroupInvitesAndJoinRequests();
|
||||
getAllGroupInvitesAndJoinRequests(D.id);
|
||||
deselectedUsers(null, true);
|
||||
}
|
||||
|
||||
@@ -1438,7 +1540,7 @@
|
||||
if (!progressTotal.value) break;
|
||||
const user = users[i];
|
||||
progressCurrent.value = i + 1;
|
||||
if (user.userId === API.currentUser.id) continue;
|
||||
if (user.userId === currentUser.value.id) continue;
|
||||
|
||||
console.log(`Blocking group join request from ${user.userId} ${i + 1}/${memberCount}`);
|
||||
try {
|
||||
@@ -1460,7 +1562,7 @@
|
||||
}
|
||||
progressCurrent.value = 0;
|
||||
progressTotal.value = 0;
|
||||
getAllGroupInvitesAndJoinRequests();
|
||||
getAllGroupInvitesAndJoinRequests(D.id);
|
||||
deselectedUsers(null, true);
|
||||
}
|
||||
|
||||
@@ -1475,7 +1577,7 @@
|
||||
if (!progressTotal.value) break;
|
||||
const user = users[i];
|
||||
progressCurrent.value = i + 1;
|
||||
if (user.userId === API.currentUser.id) continue;
|
||||
if (user.userId === currentUser.value.id) continue;
|
||||
|
||||
console.log(`Rejecting group join request from ${user.userId} ${i + 1}/${memberCount}`);
|
||||
try {
|
||||
@@ -1497,7 +1599,7 @@
|
||||
}
|
||||
progressCurrent.value = 0;
|
||||
progressTotal.value = 0;
|
||||
getAllGroupInvitesAndJoinRequests();
|
||||
getAllGroupInvitesAndJoinRequests(D.id);
|
||||
deselectedUsers(null, true);
|
||||
}
|
||||
|
||||
@@ -1511,7 +1613,7 @@
|
||||
if (!progressTotal.value) break;
|
||||
const user = users[i];
|
||||
progressCurrent.value = i + 1;
|
||||
if (user.userId === API.currentUser.id) continue;
|
||||
if (user.userId === currentUser.value.id) continue;
|
||||
|
||||
console.log(`Accepting group join request from ${user.userId} ${i + 1}/${memberCount}`);
|
||||
try {
|
||||
@@ -1533,7 +1635,7 @@
|
||||
}
|
||||
progressCurrent.value = 0;
|
||||
progressTotal.value = 0;
|
||||
getAllGroupInvitesAndJoinRequests();
|
||||
getAllGroupInvitesAndJoinRequests(D.id);
|
||||
deselectedUsers(null, true);
|
||||
}
|
||||
|
||||
@@ -1565,7 +1667,7 @@
|
||||
? groupBlockedModerationTable
|
||||
: groupJoinRequestsModerationTable;
|
||||
for (const json of args.json) {
|
||||
const ref = API.applyGroupMember(json);
|
||||
const ref = applyGroupMember(json);
|
||||
targetTable.data.push(ref);
|
||||
}
|
||||
params.offset += params.n;
|
||||
@@ -1598,7 +1700,7 @@
|
||||
? groupBlockedModerationTable
|
||||
: groupJoinRequestsModerationTable;
|
||||
for (const json of args.json) {
|
||||
const ref = API.applyGroupMember(json);
|
||||
const ref = applyGroupMember(json);
|
||||
targetTable.data.push(ref);
|
||||
}
|
||||
params.offset += params.n;
|
||||
@@ -1631,7 +1733,7 @@
|
||||
}
|
||||
|
||||
for (const json of args.json) {
|
||||
const ref = API.applyGroupMember(json);
|
||||
const ref = applyGroupMember(json);
|
||||
groupInvitesModerationTable.data.push(ref);
|
||||
}
|
||||
}
|
||||
@@ -1649,7 +1751,7 @@
|
||||
type: 'error'
|
||||
});
|
||||
} finally {
|
||||
updateIsGroupMembersLoading(false); // Use emit
|
||||
updateIsGroupMembersLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import { copyToClipboard } from '../../../composables/shared/utils';
|
||||
import { copyToClipboard } from '../../../shared/utils';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<safe-dialog
|
||||
:visible.sync="groupPostEditDialog.visible"
|
||||
:title="$t('dialog.group_post_edit.header')"
|
||||
:title="t('dialog.group_post_edit.header')"
|
||||
width="650px"
|
||||
append-to-body>
|
||||
<div v-if="groupPostEditDialog.visible">
|
||||
<h3 v-text="groupPostEditDialog.groupRef.name"></h3>
|
||||
<el-form :model="groupPostEditDialog" label-width="150px">
|
||||
<el-form-item :label="$t('dialog.group_post_edit.title')">
|
||||
<el-form-item :label="t('dialog.group_post_edit.title')">
|
||||
<el-input v-model="groupPostEditDialog.title" size="mini"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.group_post_edit.message')">
|
||||
<el-form-item :label="t('dialog.group_post_edit.message')">
|
||||
<el-input
|
||||
v-model="groupPostEditDialog.text"
|
||||
type="textarea"
|
||||
@@ -24,29 +24,27 @@
|
||||
v-if="!groupPostEditDialog.postId"
|
||||
v-model="groupPostEditDialog.sendNotification"
|
||||
size="small">
|
||||
{{ $t('dialog.group_post_edit.send_notification') }}
|
||||
{{ t('dialog.group_post_edit.send_notification') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.group_post_edit.post_visibility')">
|
||||
<el-form-item :label="t('dialog.group_post_edit.post_visibility')">
|
||||
<el-radio-group v-model="groupPostEditDialog.visibility" size="small">
|
||||
<el-radio label="public">
|
||||
{{ $t('dialog.group_post_edit.visibility_public') }}
|
||||
{{ t('dialog.group_post_edit.visibility_public') }}
|
||||
</el-radio>
|
||||
<el-radio label="group">
|
||||
{{ $t('dialog.group_post_edit.visibility_group') }}
|
||||
{{ t('dialog.group_post_edit.visibility_group') }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="groupPostEditDialog.visibility === 'group'"
|
||||
:label="$t('dialog.new_instance.roles')">
|
||||
<el-form-item v-if="groupPostEditDialog.visibility === 'group'" :label="t('dialog.new_instance.roles')">
|
||||
<el-select
|
||||
v-model="groupPostEditDialog.roleIds"
|
||||
multiple
|
||||
clearable
|
||||
:placeholder="$t('dialog.new_instance.role_placeholder')"
|
||||
:placeholder="t('dialog.new_instance.role_placeholder')"
|
||||
style="width: 100%">
|
||||
<el-option-group :label="$t('dialog.new_instance.role_placeholder')">
|
||||
<el-option-group :label="t('dialog.new_instance.role_placeholder')">
|
||||
<el-option
|
||||
v-for="role in groupPostEditDialog.groupRef?.roles"
|
||||
:key="role.id"
|
||||
@@ -60,7 +58,7 @@
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.group_post_edit.image')">
|
||||
<el-form-item :label="t('dialog.group_post_edit.image')">
|
||||
<template v-if="gallerySelectDialog.selectedFileId">
|
||||
<div style="display: inline-block; flex: none; margin-right: 5px">
|
||||
<el-popover placement="right" width="500px" trigger="click">
|
||||
@@ -80,13 +78,13 @@
|
||||
@click="showFullscreenImageDialog(gallerySelectDialog.selectedImageUrl)" />
|
||||
</el-popover>
|
||||
<el-button size="mini" style="vertical-align: top" @click="clearImageGallerySelect">
|
||||
{{ $t('dialog.invite_message.clear_selected_image') }}
|
||||
{{ t('dialog.invite_message.clear_selected_image') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button size="mini" style="margin-right: 5px" @click="showGallerySelectDialog">
|
||||
{{ $t('dialog.invite_message.select_image') }}
|
||||
{{ t('dialog.invite_message.select_image') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-form-item>
|
||||
@@ -94,13 +92,13 @@
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button size="small" @click="groupPostEditDialog.visible = false">
|
||||
{{ $t('dialog.group_post_edit.cancel') }}
|
||||
{{ t('dialog.group_post_edit.cancel') }}
|
||||
</el-button>
|
||||
<el-button v-if="groupPostEditDialog.postId" size="small" @click="editGroupPost">
|
||||
{{ $t('dialog.group_post_edit.edit_post') }}
|
||||
{{ t('dialog.group_post_edit.edit_post') }}
|
||||
</el-button>
|
||||
<el-button v-else size="small" @click="createGroupPost">
|
||||
{{ $t('dialog.group_post_edit.create_post') }}
|
||||
{{ t('dialog.group_post_edit.create_post') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<GallerySelectDialog
|
||||
@@ -110,114 +108,115 @@
|
||||
</safe-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, computed, getCurrentInstance } from 'vue';
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import { groupRequest, vrcPlusIconRequest } from '../../../api';
|
||||
import { useGalleryStore, useGroupStore } from '../../../stores';
|
||||
import GallerySelectDialog from './GallerySelectDialog.vue';
|
||||
|
||||
export default {
|
||||
name: 'GroupPostEditDialog',
|
||||
components: {
|
||||
GallerySelectDialog
|
||||
const props = defineProps({
|
||||
dialogData: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
inject: ['showFullscreenImageDialog'],
|
||||
props: {
|
||||
dialogData: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
selectedGalleryFile: { type: Object, default: () => ({}) }
|
||||
selectedGalleryFile: { type: Object, default: () => ({}) }
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:dialogData']);
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { t } = useI18n();
|
||||
|
||||
const { showFullscreenImageDialog, handleFilesList } = useGalleryStore();
|
||||
const { handleGroupPost } = useGroupStore();
|
||||
|
||||
const gallerySelectDialog = ref({
|
||||
visible: false,
|
||||
selectedFileId: '',
|
||||
selectedImageUrl: ''
|
||||
});
|
||||
const galleryTable = ref([]);
|
||||
|
||||
const groupPostEditDialog = computed({
|
||||
get() {
|
||||
return props.dialogData;
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
gallerySelectDialog: {
|
||||
visible: false,
|
||||
selectedFileId: '',
|
||||
selectedImageUrl: ''
|
||||
},
|
||||
galleryTable: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
groupPostEditDialog: {
|
||||
get() {
|
||||
return this.dialogData;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:dialog-data', value);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showGallerySelectDialog() {
|
||||
const D = this.gallerySelectDialog;
|
||||
D.visible = true;
|
||||
this.refreshGalleryTable();
|
||||
},
|
||||
async refreshGalleryTable() {
|
||||
const params = {
|
||||
n: 100,
|
||||
tag: 'gallery'
|
||||
};
|
||||
const args = await vrcPlusIconRequest.getFileList(params);
|
||||
// API.$on('FILES:LIST')
|
||||
if (args.params.tag === 'gallery') {
|
||||
this.galleryTable = args.json.reverse();
|
||||
}
|
||||
},
|
||||
editGroupPost() {
|
||||
const D = this.groupPostEditDialog;
|
||||
if (!D.groupId || !D.postId) {
|
||||
return;
|
||||
}
|
||||
const params = {
|
||||
groupId: D.groupId,
|
||||
postId: D.postId,
|
||||
title: D.title,
|
||||
text: D.text,
|
||||
roleIds: D.roleIds,
|
||||
visibility: D.visibility,
|
||||
imageId: null
|
||||
};
|
||||
if (this.gallerySelectDialog.selectedFileId) {
|
||||
params.imageId = this.gallerySelectDialog.selectedFileId;
|
||||
}
|
||||
groupRequest.editGroupPost(params).then((args) => {
|
||||
this.$message({
|
||||
message: 'Group post edited',
|
||||
type: 'success'
|
||||
});
|
||||
return args;
|
||||
});
|
||||
D.visible = false;
|
||||
},
|
||||
createGroupPost() {
|
||||
const D = this.groupPostEditDialog;
|
||||
const params = {
|
||||
groupId: D.groupId,
|
||||
title: D.title,
|
||||
text: D.text,
|
||||
roleIds: D.roleIds,
|
||||
visibility: D.visibility,
|
||||
sendNotification: D.sendNotification,
|
||||
imageId: null
|
||||
};
|
||||
if (this.gallerySelectDialog.selectedFileId) {
|
||||
params.imageId = this.gallerySelectDialog.selectedFileId;
|
||||
}
|
||||
groupRequest.createGroupPost(params).then((args) => {
|
||||
this.$message({
|
||||
message: 'Group post created',
|
||||
type: 'success'
|
||||
});
|
||||
return args;
|
||||
});
|
||||
D.visible = false;
|
||||
},
|
||||
clearImageGallerySelect() {
|
||||
const D = this.gallerySelectDialog;
|
||||
D.selectedFileId = '';
|
||||
D.selectedImageUrl = '';
|
||||
}
|
||||
set(value) {
|
||||
emit('update:dialogData', value);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
function showGallerySelectDialog() {
|
||||
const D = gallerySelectDialog.value;
|
||||
D.visible = true;
|
||||
refreshGalleryTable();
|
||||
}
|
||||
async function refreshGalleryTable() {
|
||||
const params = {
|
||||
n: 100,
|
||||
tag: 'gallery'
|
||||
};
|
||||
const args = await vrcPlusIconRequest.getFileList(params);
|
||||
handleFilesList(args);
|
||||
if (args.params.tag === 'gallery') {
|
||||
galleryTable.value = args.json.reverse();
|
||||
}
|
||||
}
|
||||
function editGroupPost() {
|
||||
const D = groupPostEditDialog.value;
|
||||
if (!D.groupId || !D.postId) {
|
||||
return;
|
||||
}
|
||||
const params = {
|
||||
groupId: D.groupId,
|
||||
postId: D.postId,
|
||||
title: D.title,
|
||||
text: D.text,
|
||||
roleIds: D.roleIds,
|
||||
visibility: D.visibility,
|
||||
imageId: null
|
||||
};
|
||||
if (gallerySelectDialog.value.selectedFileId) {
|
||||
params.imageId = gallerySelectDialog.value.selectedFileId;
|
||||
}
|
||||
groupRequest.editGroupPost(params).then((args) => {
|
||||
handleGroupPost();
|
||||
proxy.$message({
|
||||
message: 'Group post edited',
|
||||
type: 'success'
|
||||
});
|
||||
return args;
|
||||
});
|
||||
D.visible = false;
|
||||
}
|
||||
function createGroupPost() {
|
||||
const D = groupPostEditDialog.value;
|
||||
const params = {
|
||||
groupId: D.groupId,
|
||||
title: D.title,
|
||||
text: D.text,
|
||||
roleIds: D.roleIds,
|
||||
visibility: D.visibility,
|
||||
sendNotification: D.sendNotification,
|
||||
imageId: null
|
||||
};
|
||||
if (gallerySelectDialog.value.selectedFileId) {
|
||||
params.imageId = gallerySelectDialog.value.selectedFileId;
|
||||
}
|
||||
groupRequest.createGroupPost(params).then((args) => {
|
||||
handleGroupPost();
|
||||
proxy.$message({
|
||||
message: 'Group post created',
|
||||
type: 'success'
|
||||
});
|
||||
return args;
|
||||
});
|
||||
D.visible = false;
|
||||
}
|
||||
function clearImageGallerySelect() {
|
||||
const D = gallerySelectDialog.value;
|
||||
D.selectedFileId = '';
|
||||
D.selectedImageUrl = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user