添加红包功能
This commit is contained in:
@@ -3,17 +3,12 @@
|
||||
<Navigation :title="title">
|
||||
<template #left>
|
||||
<div @click="back">
|
||||
<Icon
|
||||
:file="backSVG"
|
||||
/>
|
||||
<Icon :file="backSVG" />
|
||||
</div>
|
||||
</template>
|
||||
<template #right>
|
||||
<div @click="onNavigationBarButtonTap">
|
||||
<Icon
|
||||
v-if="isGroup"
|
||||
:file="More"
|
||||
/>
|
||||
<Icon v-if="isGroup" :file="More" />
|
||||
</div>
|
||||
</template>
|
||||
</Navigation>
|
||||
@@ -21,78 +16,78 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, ref } from '../../../adapter-vue';
|
||||
import {
|
||||
TUIStore,
|
||||
StoreName,
|
||||
IConversationModel,
|
||||
TUITranslateService,
|
||||
} from '@tencentcloud/chat-uikit-engine-lite';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import Navigation from '../../common/Navigation/index.vue';
|
||||
import Icon from '../../common/Icon.vue';
|
||||
import More from '../../../assets/icon/more.svg';
|
||||
import backSVG from '../../../assets/icon/back.svg';
|
||||
import { onMounted, onUnmounted, ref } from '../../../adapter-vue'
|
||||
import {
|
||||
TUIStore,
|
||||
StoreName,
|
||||
IConversationModel,
|
||||
TUITranslateService
|
||||
} from '@tencentcloud/chat-uikit-engine-lite'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import Navigation from '../../common/Navigation/index.vue'
|
||||
import Icon from '../../common/Icon.vue'
|
||||
import More from '../../../assets/icon/more.svg'
|
||||
import backSVG from '../../../assets/icon/back.svg'
|
||||
|
||||
const emits = defineEmits(['openGroupManagement']);
|
||||
const props = defineProps(['isGroup']);
|
||||
const emits = defineEmits(['openGroupManagement'])
|
||||
const props = defineProps(['isGroup'])
|
||||
|
||||
const currentConversation = ref<IConversationModel>();
|
||||
const typingStatus = ref(false);
|
||||
const title = ref('');
|
||||
const currentConversation = ref<IConversationModel>()
|
||||
const typingStatus = ref(false)
|
||||
const title = ref('')
|
||||
|
||||
const setChatHeaderContent = (content: string) => {
|
||||
title.value = content || '云通信 IM';
|
||||
};
|
||||
|
||||
const onNavigationBarButtonTap = () => {
|
||||
if (props.isGroup) {
|
||||
emits('openGroupManagement');
|
||||
const setChatHeaderContent = (content: string) => {
|
||||
title.value = content || '云通信 IM'
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated,
|
||||
});
|
||||
TUIStore.watch(StoreName.CHAT, {
|
||||
typingStatus: onTypingStatusUpdated,
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
TUIStore.unwatch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated,
|
||||
});
|
||||
TUIStore.unwatch(StoreName.CHAT, {
|
||||
typingStatus: onTypingStatusUpdated,
|
||||
});
|
||||
});
|
||||
|
||||
onLoad(() => {
|
||||
setChatHeaderContent(currentConversation.value?.getShowName());
|
||||
});
|
||||
|
||||
function onCurrentConversationUpdated(conversation: IConversationModel) {
|
||||
currentConversation.value = conversation;
|
||||
if (!typingStatus.value) {
|
||||
setChatHeaderContent(currentConversation?.value?.getShowName());
|
||||
const onNavigationBarButtonTap = () => {
|
||||
if (props.isGroup) {
|
||||
emits('openGroupManagement')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onTypingStatusUpdated(status: boolean) {
|
||||
typingStatus.value = status;
|
||||
if (typingStatus.value) {
|
||||
setChatHeaderContent(TUITranslateService.t('TUIChat.对方正在输入'));
|
||||
} else {
|
||||
setChatHeaderContent(currentConversation.value?.getShowName());
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated
|
||||
})
|
||||
TUIStore.watch(StoreName.CHAT, {
|
||||
typingStatus: onTypingStatusUpdated
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
TUIStore.unwatch(StoreName.CONV, {
|
||||
currentConversation: onCurrentConversationUpdated
|
||||
})
|
||||
TUIStore.unwatch(StoreName.CHAT, {
|
||||
typingStatus: onTypingStatusUpdated
|
||||
})
|
||||
})
|
||||
|
||||
onLoad(() => {
|
||||
setChatHeaderContent(currentConversation.value?.getShowName())
|
||||
})
|
||||
|
||||
function onCurrentConversationUpdated(
|
||||
conversation: IConversationModel
|
||||
) {
|
||||
currentConversation.value = conversation
|
||||
if (!typingStatus.value) {
|
||||
setChatHeaderContent(currentConversation?.value?.getShowName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function back() {
|
||||
uni.navigateBack();
|
||||
}
|
||||
function onTypingStatusUpdated(status: boolean) {
|
||||
typingStatus.value = status
|
||||
if (typingStatus.value) {
|
||||
setChatHeaderContent(TUITranslateService.t('TUIChat.对方正在输入'))
|
||||
} else {
|
||||
setChatHeaderContent(currentConversation.value?.getShowName())
|
||||
}
|
||||
}
|
||||
|
||||
function back() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
:class="[
|
||||
'message-input-toolbar',
|
||||
'message-input-toolbar-h5',
|
||||
'message-input-toolbar-uni',
|
||||
'message-input-toolbar-uni'
|
||||
]"
|
||||
>
|
||||
<div v-if="props.displayType === 'emojiPicker'">
|
||||
@@ -20,18 +20,17 @@
|
||||
:class="[
|
||||
'message-input-toolbar-list',
|
||||
'message-input-toolbar-h5-list',
|
||||
'message-input-toolbar-uni-list',
|
||||
'message-input-toolbar-uni-list'
|
||||
]"
|
||||
>
|
||||
<CameraUpload
|
||||
v-if="featureConfig.InputCamera"
|
||||
/>
|
||||
<AlbumUpload
|
||||
v-if="featureConfig.InputAlbum"
|
||||
/>
|
||||
<CameraUpload v-if="featureConfig.InputCamera" />
|
||||
<AlbumUpload v-if="featureConfig.InputAlbum" />
|
||||
<template v-if="currentExtensionList.length > 0">
|
||||
<div
|
||||
v-for="(extension, index) in currentExtensionList.slice(0, slicePos)"
|
||||
v-for="(extension, index) in currentExtensionList.slice(
|
||||
0,
|
||||
slicePos
|
||||
)"
|
||||
:key="index"
|
||||
>
|
||||
<ToolbarItemContainer
|
||||
@@ -64,6 +63,7 @@
|
||||
v-if="featureConfig.InputEvaluation"
|
||||
@onDialogPopupShowOrHide="handleSwiperDotShow"
|
||||
/>
|
||||
<RedEnvelope />
|
||||
</template>
|
||||
</swiper-item>
|
||||
<swiper-item
|
||||
@@ -71,11 +71,13 @@
|
||||
:class="[
|
||||
'message-input-toolbar-list',
|
||||
'message-input-toolbar-h5-list',
|
||||
'message-input-toolbar-uni-list',
|
||||
'message-input-toolbar-uni-list'
|
||||
]"
|
||||
>
|
||||
<div
|
||||
v-for="(extension, index) in currentExtensionList.slice(slicePos)"
|
||||
v-for="(extension, index) in currentExtensionList.slice(
|
||||
slicePos
|
||||
)"
|
||||
:key="index"
|
||||
>
|
||||
<ToolbarItemContainer
|
||||
@@ -117,188 +119,217 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TUIChatEngine, {
|
||||
IConversationModel,
|
||||
TUIStore,
|
||||
StoreName,
|
||||
TUIReportService,
|
||||
} from '@tencentcloud/chat-uikit-engine-lite';
|
||||
import TUICore, { ExtensionInfo, TUIConstants } from '@tencentcloud/tui-core-lite';
|
||||
import { ref, onUnmounted, onMounted } from '../../../adapter-vue';
|
||||
import AlbumUpload from './album-upload/index.vue';
|
||||
import CameraUpload from './camera-upload/index.vue';
|
||||
import Evaluate from './evaluate/index.vue';
|
||||
import Words from './words/index.vue';
|
||||
import ToolbarItemContainer from './toolbar-item-container/index.vue';
|
||||
import EmojiPickerDialog from './emoji-picker/emoji-picker-dialog.vue';
|
||||
import UserSelector from './user-selector/index.vue';
|
||||
import TUIChatConfig from '../config';
|
||||
import { enableSampleTaskStatus } from '../../../utils/enableSampleTaskStatus';
|
||||
import { ToolbarDisplayType } from '../../../interface';
|
||||
import OfflinePushInfoManager, { PUSH_SCENE } from '../offlinePushInfoManager/index';
|
||||
import TUIChatEngine, {
|
||||
IConversationModel,
|
||||
TUIStore,
|
||||
StoreName,
|
||||
TUIReportService
|
||||
} from '@tencentcloud/chat-uikit-engine-lite'
|
||||
import TUICore, {
|
||||
ExtensionInfo,
|
||||
TUIConstants
|
||||
} from '@tencentcloud/tui-core-lite'
|
||||
import { ref, onUnmounted, onMounted } from '../../../adapter-vue'
|
||||
import AlbumUpload from './album-upload/index.vue'
|
||||
import CameraUpload from './camera-upload/index.vue'
|
||||
import Evaluate from './evaluate/index.vue'
|
||||
import RedEnvelope from './red-envelope/index.vue'
|
||||
import Words from './words/index.vue'
|
||||
import ToolbarItemContainer from './toolbar-item-container/index.vue'
|
||||
import EmojiPickerDialog from './emoji-picker/emoji-picker-dialog.vue'
|
||||
import UserSelector from './user-selector/index.vue'
|
||||
import TUIChatConfig from '../config'
|
||||
import { enableSampleTaskStatus } from '../../../utils/enableSampleTaskStatus'
|
||||
import { ToolbarDisplayType } from '../../../interface'
|
||||
import OfflinePushInfoManager, {
|
||||
PUSH_SCENE
|
||||
} from '../offlinePushInfoManager/index'
|
||||
|
||||
interface IProps {
|
||||
displayType: ToolbarDisplayType;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
});
|
||||
|
||||
const emits = defineEmits(['changeToolbarDisplayType']);
|
||||
|
||||
const currentConversation = ref<IConversationModel>();
|
||||
const isGroup = ref<boolean>(false);
|
||||
const selectorShowType = ref<string>('');
|
||||
const userSelectorRef = ref();
|
||||
const currentUserSelectorExtension = ref<ExtensionInfo | null>();
|
||||
const currentExtensionList = ref<ExtensionInfo[]>([]);
|
||||
const isSwiperIndicatorDotsEnable = ref<boolean>(false);
|
||||
const featureConfig = TUIChatConfig.getFeatureConfig();
|
||||
const neededCountFirstPage = ref<number>(8);
|
||||
const slicePos = ref<number>(0);
|
||||
|
||||
const computeToolbarPaging = () => {
|
||||
if (featureConfig.InputAlbum && featureConfig.InputCamera) {
|
||||
neededCountFirstPage.value -= 2;
|
||||
} else if (featureConfig.InputAlbum || featureConfig.InputCamera) {
|
||||
neededCountFirstPage.value -= 1;
|
||||
interface IProps {
|
||||
displayType: ToolbarDisplayType
|
||||
}
|
||||
|
||||
slicePos.value = neededCountFirstPage.value;
|
||||
neededCountFirstPage.value -= currentExtensionList.value.length;
|
||||
const props = withDefaults(defineProps<IProps>(), {})
|
||||
|
||||
if (neededCountFirstPage.value === 1) {
|
||||
isSwiperIndicatorDotsEnable.value = (featureConfig.InputEvaluation && featureConfig.InputQuickReplies);
|
||||
} else if (neededCountFirstPage.value < 1) {
|
||||
isSwiperIndicatorDotsEnable.value = featureConfig.InputEvaluation || featureConfig.InputQuickReplies;
|
||||
}
|
||||
};
|
||||
const emits = defineEmits(['changeToolbarDisplayType'])
|
||||
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CUSTOM, {
|
||||
activeConversation: onActiveConversationUpdate,
|
||||
});
|
||||
});
|
||||
const currentConversation = ref<IConversationModel>()
|
||||
const isGroup = ref<boolean>(false)
|
||||
const selectorShowType = ref<string>('')
|
||||
const userSelectorRef = ref()
|
||||
const currentUserSelectorExtension = ref<ExtensionInfo | null>()
|
||||
const currentExtensionList = ref<ExtensionInfo[]>([])
|
||||
const isSwiperIndicatorDotsEnable = ref<boolean>(false)
|
||||
const featureConfig = TUIChatConfig.getFeatureConfig()
|
||||
const neededCountFirstPage = ref<number>(8)
|
||||
const slicePos = ref<number>(0)
|
||||
|
||||
onUnmounted(() => {
|
||||
TUIStore.unwatch(StoreName.CUSTOM, {
|
||||
activeConversation: onActiveConversationUpdate,
|
||||
});
|
||||
});
|
||||
|
||||
const onActiveConversationUpdate = (conversationID: string) => {
|
||||
if (!conversationID) {
|
||||
return;
|
||||
}
|
||||
if (conversationID !== currentConversation.value?.conversationID) {
|
||||
getExtensionList();
|
||||
computeToolbarPaging();
|
||||
currentConversation.value = TUIStore.getData(StoreName.CONV, 'currentConversation');
|
||||
isGroup.value = conversationID.startsWith(TUIChatEngine.TYPES.CONV_GROUP);
|
||||
}
|
||||
};
|
||||
|
||||
const getExtensionList = () => {
|
||||
const chatType = TUIChatConfig.getChatType();
|
||||
const params: Record<string, boolean | string> = { chatType };
|
||||
// Backward compatibility: When callkit does not have chatType judgment, use filterVoice and filterVideo to filter
|
||||
if (chatType === TUIConstants.TUIChat.TYPE.CUSTOMER_SERVICE) {
|
||||
params.filterVoice = true;
|
||||
params.filterVideo = true;
|
||||
enableSampleTaskStatus('customerService');
|
||||
}
|
||||
// uni-app build ios app has null in last index need to filter
|
||||
currentExtensionList.value = [
|
||||
...TUICore.getExtensionList(TUIConstants.TUIChat.EXTENSION.INPUT_MORE.EXT_ID, params),
|
||||
].filter((extension: ExtensionInfo) => {
|
||||
if (extension?.data?.name === 'search') {
|
||||
return featureConfig.MessageSearch;
|
||||
const computeToolbarPaging = () => {
|
||||
if (featureConfig.InputAlbum && featureConfig.InputCamera) {
|
||||
neededCountFirstPage.value -= 2
|
||||
} else if (featureConfig.InputAlbum || featureConfig.InputCamera) {
|
||||
neededCountFirstPage.value -= 1
|
||||
}
|
||||
return true;
|
||||
});
|
||||
reportExtension(currentExtensionList.value);
|
||||
};
|
||||
|
||||
function reportExtension(extensionList: ExtensionInfo[]) {
|
||||
extensionList.forEach((extension: ExtensionInfo) => {
|
||||
const _name = extension?.data?.name;
|
||||
if (_name === 'voiceCall') {
|
||||
TUIReportService.reportFeature(203, 'voice-call');
|
||||
} else if (_name === 'videoCall') {
|
||||
TUIReportService.reportFeature(203, 'video-call');
|
||||
} else if (_name === 'quickRoom') {
|
||||
TUIReportService.reportFeature(204);
|
||||
slicePos.value = neededCountFirstPage.value
|
||||
neededCountFirstPage.value -= currentExtensionList.value.length
|
||||
|
||||
if (neededCountFirstPage.value === 1) {
|
||||
isSwiperIndicatorDotsEnable.value =
|
||||
featureConfig.InputEvaluation && featureConfig.InputQuickReplies
|
||||
} else if (neededCountFirstPage.value < 1) {
|
||||
isSwiperIndicatorDotsEnable.value =
|
||||
featureConfig.InputEvaluation || featureConfig.InputQuickReplies
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// handle extensions onclick
|
||||
const onExtensionClick = (extension: ExtensionInfo) => {
|
||||
// uniapp vue2 build wx lose listener proto
|
||||
const extensionModel = currentExtensionList.value.find(
|
||||
targetExtension => targetExtension?.data?.name === extension?.data?.name,
|
||||
);
|
||||
switch (extensionModel?.data?.name) {
|
||||
case 'voiceCall':
|
||||
onCallExtensionClicked(extensionModel, 1);
|
||||
break;
|
||||
case 'videoCall':
|
||||
onCallExtensionClicked(extensionModel, 2);
|
||||
break;
|
||||
case 'search':
|
||||
extensionModel?.listener?.onClicked?.();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const onCallExtensionClicked = (extension: ExtensionInfo, callType: number) => {
|
||||
selectorShowType.value = extension?.data?.name;
|
||||
if (currentConversation?.value?.type === TUIChatEngine.TYPES.CONV_C2C) {
|
||||
extension?.listener?.onClicked?.({
|
||||
userIDList: [currentConversation?.value?.conversationID?.slice(3)],
|
||||
type: callType,
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CUSTOM, {
|
||||
activeConversation: onActiveConversationUpdate
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
TUIStore.unwatch(StoreName.CUSTOM, {
|
||||
activeConversation: onActiveConversationUpdate
|
||||
})
|
||||
})
|
||||
|
||||
const onActiveConversationUpdate = (conversationID: string) => {
|
||||
if (!conversationID) {
|
||||
return
|
||||
}
|
||||
if (conversationID !== currentConversation.value?.conversationID) {
|
||||
getExtensionList()
|
||||
computeToolbarPaging()
|
||||
currentConversation.value = TUIStore.getData(
|
||||
StoreName.CONV,
|
||||
'currentConversation'
|
||||
)
|
||||
isGroup.value = conversationID.startsWith(
|
||||
TUIChatEngine.TYPES.CONV_GROUP
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const getExtensionList = () => {
|
||||
const chatType = TUIChatConfig.getChatType()
|
||||
const params: Record<string, boolean | string> = { chatType }
|
||||
// Backward compatibility: When callkit does not have chatType judgment, use filterVoice and filterVideo to filter
|
||||
if (chatType === TUIConstants.TUIChat.TYPE.CUSTOMER_SERVICE) {
|
||||
params.filterVoice = true
|
||||
params.filterVideo = true
|
||||
enableSampleTaskStatus('customerService')
|
||||
}
|
||||
// uni-app build ios app has null in last index need to filter
|
||||
currentExtensionList.value = [
|
||||
...TUICore.getExtensionList(
|
||||
TUIConstants.TUIChat.EXTENSION.INPUT_MORE.EXT_ID,
|
||||
params
|
||||
)
|
||||
].filter((extension: ExtensionInfo) => {
|
||||
if (extension?.data?.name === 'search') {
|
||||
return featureConfig.MessageSearch
|
||||
}
|
||||
return true
|
||||
})
|
||||
reportExtension(currentExtensionList.value)
|
||||
}
|
||||
|
||||
function reportExtension(extensionList: ExtensionInfo[]) {
|
||||
extensionList.forEach((extension: ExtensionInfo) => {
|
||||
const _name = extension?.data?.name
|
||||
if (_name === 'voiceCall') {
|
||||
TUIReportService.reportFeature(203, 'voice-call')
|
||||
} else if (_name === 'videoCall') {
|
||||
TUIReportService.reportFeature(203, 'video-call')
|
||||
} else if (_name === 'quickRoom') {
|
||||
TUIReportService.reportFeature(204)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// handle extensions onclick
|
||||
const onExtensionClick = (extension: ExtensionInfo) => {
|
||||
// uniapp vue2 build wx lose listener proto
|
||||
const extensionModel = currentExtensionList.value.find(
|
||||
targetExtension =>
|
||||
targetExtension?.data?.name === extension?.data?.name
|
||||
)
|
||||
switch (extensionModel?.data?.name) {
|
||||
case 'voiceCall':
|
||||
onCallExtensionClicked(extensionModel, 1)
|
||||
break
|
||||
case 'videoCall':
|
||||
onCallExtensionClicked(extensionModel, 2)
|
||||
break
|
||||
case 'search':
|
||||
extensionModel?.listener?.onClicked?.()
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const onCallExtensionClicked = (
|
||||
extension: ExtensionInfo,
|
||||
callType: number
|
||||
) => {
|
||||
selectorShowType.value = extension?.data?.name
|
||||
if (
|
||||
currentConversation?.value?.type === TUIChatEngine.TYPES.CONV_C2C
|
||||
) {
|
||||
extension?.listener?.onClicked?.({
|
||||
userIDList: [
|
||||
currentConversation?.value?.conversationID?.slice(3)
|
||||
],
|
||||
type: callType,
|
||||
callParams: {
|
||||
offlinePushInfo: OfflinePushInfoManager.getOfflinePushInfo(
|
||||
PUSH_SCENE.CALL
|
||||
)
|
||||
}
|
||||
})
|
||||
} else if (isGroup.value) {
|
||||
currentUserSelectorExtension.value = extension
|
||||
userSelectorRef?.value?.toggleShow &&
|
||||
userSelectorRef.value.toggleShow(true)
|
||||
}
|
||||
}
|
||||
|
||||
const genExtensionIcon = (extension: any) => extension?.icon
|
||||
const genExtensionText = (extension: any) => extension?.text
|
||||
|
||||
const onUserSelectorSubmit = (selectedInfo: any) => {
|
||||
currentUserSelectorExtension.value?.listener?.onClicked?.({
|
||||
...selectedInfo,
|
||||
callParams: {
|
||||
offlinePushInfo: OfflinePushInfoManager.getOfflinePushInfo(PUSH_SCENE.CALL),
|
||||
},
|
||||
});
|
||||
} else if (isGroup.value) {
|
||||
currentUserSelectorExtension.value = extension;
|
||||
userSelectorRef?.value?.toggleShow && userSelectorRef.value.toggleShow(true);
|
||||
offlinePushInfo: OfflinePushInfoManager.getOfflinePushInfo(
|
||||
PUSH_SCENE.CALL
|
||||
)
|
||||
}
|
||||
})
|
||||
currentUserSelectorExtension.value = null
|
||||
}
|
||||
};
|
||||
|
||||
const genExtensionIcon = (extension: any) => extension?.icon;
|
||||
const genExtensionText = (extension: any) => extension?.text;
|
||||
const onUserSelectorCancel = () => {
|
||||
currentUserSelectorExtension.value = null
|
||||
}
|
||||
|
||||
const onUserSelectorSubmit = (selectedInfo: any) => {
|
||||
currentUserSelectorExtension.value?.listener?.onClicked?.({
|
||||
...selectedInfo,
|
||||
callParams: {
|
||||
offlinePushInfo: OfflinePushInfoManager.getOfflinePushInfo(PUSH_SCENE.CALL),
|
||||
},
|
||||
});
|
||||
currentUserSelectorExtension.value = null;
|
||||
};
|
||||
|
||||
const onUserSelectorCancel = () => {
|
||||
currentUserSelectorExtension.value = null;
|
||||
};
|
||||
|
||||
const handleSwiperDotShow = (showStatus: boolean) => {
|
||||
isSwiperIndicatorDotsEnable.value = (neededCountFirstPage.value <= 1 && !showStatus);
|
||||
emits('changeToolbarDisplayType', showStatus ? 'dialog' : 'tools');
|
||||
};
|
||||
const handleSwiperDotShow = (showStatus: boolean) => {
|
||||
isSwiperIndicatorDotsEnable.value =
|
||||
neededCountFirstPage.value <= 1 && !showStatus
|
||||
emits('changeToolbarDisplayType', showStatus ? 'dialog' : 'tools')
|
||||
}
|
||||
</script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
};
|
||||
export default {
|
||||
options: {
|
||||
styleIsolation: 'shared'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
@import '../../../assets/styles/common';
|
||||
@import './style/uni';
|
||||
@import '../../../assets/styles/common';
|
||||
@import './style/uni';
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import ToolbarItemContainer from '../toolbar-item-container/index.vue'
|
||||
import custom from '../../../../assets/icon/red-packet.svg'
|
||||
import { isUniFrameWork } from '../../../../utils/env'
|
||||
|
||||
const evaluateIcon = custom;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ToolbarItemContainer
|
||||
:iconFile="evaluateIcon"
|
||||
:iconWidth="isUniFrameWork ? '26px' : '20px'"
|
||||
:iconHeight="isUniFrameWork ? '26px' : '20px'"
|
||||
title="红包"
|
||||
>
|
||||
<view>弹出窗口</view>
|
||||
</ToolbarItemContainer>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@@ -5,172 +5,175 @@ import TUIChatEngine, {
|
||||
TUIUserService,
|
||||
TUITranslateService,
|
||||
AddFriendParams,
|
||||
JoinGroupParams,
|
||||
} from '@tencentcloud/chat-uikit-engine-lite';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
import { Toast, TOAST_TYPE } from '../../common/Toast/index';
|
||||
JoinGroupParams
|
||||
} from '@tencentcloud/chat-uikit-engine-lite'
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api'
|
||||
import { Toast, TOAST_TYPE } from '../../common/Toast/index'
|
||||
import { deleteImGroup, quitImGroup } from '../../../../api/tui-kit'
|
||||
import { switchTab } from '../../../../utils/router'
|
||||
|
||||
export const generateAvatar = (item: any): string => {
|
||||
return (
|
||||
item?.avatar
|
||||
|| item?.profile?.avatar
|
||||
|| (item?.groupID && 'https://web.sdk.qcloud.com/im/assets/images/Public.svg')
|
||||
|| 'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'
|
||||
);
|
||||
};
|
||||
item?.avatar ||
|
||||
item?.profile?.avatar ||
|
||||
(item?.groupID &&
|
||||
'https://web.sdk.qcloud.com/im/assets/images/Public.svg') ||
|
||||
'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'
|
||||
)
|
||||
}
|
||||
|
||||
export const generateName = (item: any): string => {
|
||||
return (
|
||||
item?.remark
|
||||
|| item?.name
|
||||
|| item?.profile?.nick
|
||||
|| item?.nick
|
||||
|| item?.groupID
|
||||
|| item?.userID
|
||||
|| ''
|
||||
);
|
||||
};
|
||||
item?.remark ||
|
||||
item?.name ||
|
||||
item?.profile?.nick ||
|
||||
item?.nick ||
|
||||
item?.groupID ||
|
||||
item?.userID ||
|
||||
''
|
||||
)
|
||||
}
|
||||
|
||||
export const generateContactInfoName = (item: any): string => {
|
||||
return (
|
||||
item?.name
|
||||
|| item?.profile?.nick
|
||||
|| item?.nick
|
||||
|| item?.groupID
|
||||
|| item?.userID
|
||||
|| ''
|
||||
);
|
||||
};
|
||||
item?.name ||
|
||||
item?.profile?.nick ||
|
||||
item?.nick ||
|
||||
item?.groupID ||
|
||||
item?.userID ||
|
||||
''
|
||||
)
|
||||
}
|
||||
|
||||
// Parse the basic information display content of the contactInfo module
|
||||
// Group information display: group ID group type
|
||||
// User information display: user ID personal signature
|
||||
export const generateContactInfoBasic = (
|
||||
contactInfo: any,
|
||||
): any[] => {
|
||||
export const generateContactInfoBasic = (contactInfo: any): any[] => {
|
||||
const res = [
|
||||
{
|
||||
label: contactInfo?.groupID ? '群ID' : 'ID',
|
||||
data: contactInfo?.groupID || contactInfo?.userID || '',
|
||||
},
|
||||
];
|
||||
data: contactInfo?.groupID || contactInfo?.userID || ''
|
||||
}
|
||||
]
|
||||
if (!isApplicationType(contactInfo)) {
|
||||
res.push({
|
||||
label: contactInfo?.groupID ? '群类型' : '个性签名',
|
||||
data: contactInfo?.type || contactInfo?.profile?.selfSignature || '',
|
||||
});
|
||||
data: contactInfo?.type || contactInfo?.profile?.selfSignature || ''
|
||||
})
|
||||
}
|
||||
return res;
|
||||
};
|
||||
return res
|
||||
}
|
||||
|
||||
export const isApplicationType = (info: any) => {
|
||||
return (
|
||||
info?.type === TUIChatEngine?.TYPES?.SNS_APPLICATION_SENT_TO_ME
|
||||
|| info?.type === TUIChatEngine?.TYPES?.SNS_APPLICATION_SENT_BY_ME
|
||||
);
|
||||
};
|
||||
info?.type === TUIChatEngine?.TYPES?.SNS_APPLICATION_SENT_TO_ME ||
|
||||
info?.type === TUIChatEngine?.TYPES?.SNS_APPLICATION_SENT_BY_ME
|
||||
)
|
||||
}
|
||||
|
||||
export const isFriend = (info: any): Promise<boolean> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (info?.groupID || !info?.userID) {
|
||||
resolve(false);
|
||||
return;
|
||||
resolve(false)
|
||||
return
|
||||
}
|
||||
if (info?.addTime) {
|
||||
resolve(true);
|
||||
return;
|
||||
resolve(true)
|
||||
return
|
||||
}
|
||||
TUIFriendService.checkFriend({
|
||||
userIDList: [info?.userID],
|
||||
type: TUIChatEngine.TYPES.SNS_CHECK_TYPE_BOTH,
|
||||
type: TUIChatEngine.TYPES.SNS_CHECK_TYPE_BOTH
|
||||
})
|
||||
.then((res: any) => {
|
||||
switch (res?.data?.successUserIDList[0]?.relation) {
|
||||
// No friend relationship: A does not have B in his friend list, and B does not have A in his friend list
|
||||
case TUIChatEngine.TYPES.SNS_TYPE_NO_RELATION:
|
||||
resolve(false);
|
||||
break;
|
||||
resolve(false)
|
||||
break
|
||||
// Single-item friend: A has B in his friend list, but B does not have A in his friend list
|
||||
case TUIChatEngine.TYPES.SNS_TYPE_A_WITH_B:
|
||||
resolve(false);
|
||||
break;
|
||||
resolve(false)
|
||||
break
|
||||
// Single-item friend: A does not have B in his friend list, but B has A in his friend list
|
||||
case TUIChatEngine.TYPES.SNS_TYPE_B_WITH_A:
|
||||
resolve(false);
|
||||
break;
|
||||
resolve(false)
|
||||
break
|
||||
// Two-way friendship
|
||||
case TUIChatEngine.TYPES.SNS_TYPE_BOTH_WAY:
|
||||
resolve(true);
|
||||
break;
|
||||
resolve(true)
|
||||
break
|
||||
default:
|
||||
resolve(false);
|
||||
break;
|
||||
resolve(false)
|
||||
break
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('checkFriend error', error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
console.warn('checkFriend error', error)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Change friend‘s remark
|
||||
export const updateFriendRemark = (userID: string, remark: string) => {
|
||||
// eslint-disable-next-line no-control-regex
|
||||
if (remark?.replace(/[^\u0000-\u00ff]/g, 'aa')?.length > 96) {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.修改备注失败: 备注长度不得超过 96 字节'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
return;
|
||||
message: TUITranslateService.t(
|
||||
'TUIContact.修改备注失败: 备注长度不得超过 96 字节'
|
||||
),
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
return
|
||||
}
|
||||
TUIFriendService.updateFriend({
|
||||
userID,
|
||||
remark,
|
||||
remark
|
||||
})
|
||||
.then(() => {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.修改备注成功'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('update friend remark failed:', error);
|
||||
console.warn('update friend remark failed:', error)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.修改备注失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
});
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Delete one friend
|
||||
export const deleteFriend = (userID: string) => {
|
||||
TUIFriendService.deleteFriend({
|
||||
userIDList: [userID],
|
||||
type: TUIChatEngine.TYPES.SNS_DELETE_TYPE_BOTH,
|
||||
type: TUIChatEngine.TYPES.SNS_DELETE_TYPE_BOTH
|
||||
})
|
||||
.then((res: any) => {
|
||||
const { successUserIDList } = res.data;
|
||||
const { successUserIDList } = res.data
|
||||
if (successUserIDList[0].userID === userID) {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.删除好友成功'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
} else {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.删除好友失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('delete friend failed:', error);
|
||||
console.warn('delete friend failed:', error)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.删除好友失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
});
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Add friend
|
||||
export const addFriend = (params: AddFriendParams) => {
|
||||
@@ -178,54 +181,54 @@ export const addFriend = (params: AddFriendParams) => {
|
||||
.then(() => {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.申请已发送'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('delete friend failed:', error);
|
||||
console.warn('delete friend failed:', error)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.申请发送失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
});
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Enter conversation
|
||||
export const enterConversation = (item: any) => {
|
||||
const conversationID = item?.groupID
|
||||
? `GROUP${item?.groupID}`
|
||||
: `C2C${item?.userID}`;
|
||||
: `C2C${item?.userID}`
|
||||
TUIConversationService.switchConversation(conversationID).catch(
|
||||
(error: any) => {
|
||||
console.warn('switch conversation failed:', error);
|
||||
console.warn('switch conversation failed:', error)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.进入会话失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
},
|
||||
);
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Accept friend application
|
||||
export const acceptFriendApplication = (userID: string) => {
|
||||
TUIFriendService.acceptFriendApplication({
|
||||
userID,
|
||||
type: TUIChatEngine.TYPES.SNS_APPLICATION_AGREE_AND_ADD,
|
||||
type: TUIChatEngine.TYPES.SNS_APPLICATION_AGREE_AND_ADD
|
||||
})
|
||||
.then(() => {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.添加好友成功'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('accept friend application failed:', error);
|
||||
console.warn('accept friend application failed:', error)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.同意好友申请失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
});
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Refuse friend application
|
||||
export const refuseFriendApplication = (userID: string) => {
|
||||
@@ -233,127 +236,164 @@ export const refuseFriendApplication = (userID: string) => {
|
||||
.then(() => {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.拒绝成功'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('accept friend application failed:', error);
|
||||
console.warn('accept friend application failed:', error)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.拒绝好友申请失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
});
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Dismiss group
|
||||
export const dismissGroup = (groupID: string) => {
|
||||
TUIGroupService.dismissGroup(groupID)
|
||||
deleteImGroup(groupID)
|
||||
.then(() => {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.解散群聊成功'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
TUIGlobal?.updateContactSearch && TUIGlobal?.updateContactSearch();
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
TUIGlobal?.updateContactSearch && TUIGlobal?.updateContactSearch()
|
||||
switchTab('/TUIKit/components/TUIConversation/index')
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('dismiss group failed:', error);
|
||||
console.warn('dismiss group failed:', error)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.解散群聊失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
});
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
})
|
||||
// TUIGroupService.dismissGroup(groupID)
|
||||
// .then(() => {
|
||||
// Toast({
|
||||
// message: TUITranslateService.t('TUIContact.解散群聊成功'),
|
||||
// type: TOAST_TYPE.SUCCESS,
|
||||
// });
|
||||
// TUIGlobal?.updateContactSearch && TUIGlobal?.updateContactSearch();
|
||||
// })
|
||||
// .catch((error: any) => {
|
||||
// console.warn('dismiss group failed:', error);
|
||||
// Toast({
|
||||
// message: TUITranslateService.t('TUIContact.解散群聊失败'),
|
||||
// type: TOAST_TYPE.ERROR,
|
||||
// });
|
||||
// });
|
||||
}
|
||||
|
||||
// Quit group
|
||||
export const quitGroup = (groupID: string) => {
|
||||
TUIGroupService.quitGroup(groupID)
|
||||
console.log('222')
|
||||
quitImGroup(groupID)
|
||||
.then(() => {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.退出群组成功'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
|
||||
switchTab('/TUIKit/components/TUIConversation/index')
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('quit group failed:', error);
|
||||
console.warn('quit group failed:', error)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.退出群组失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
});
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
})
|
||||
|
||||
// TUIGroupService.quitGroup(groupID)
|
||||
// .then(() => {
|
||||
// Toast({
|
||||
// message: TUITranslateService.t('TUIContact.退出群组成功'),
|
||||
// type: TOAST_TYPE.SUCCESS,
|
||||
// });
|
||||
// })
|
||||
// .catch((error: any) => {
|
||||
// console.warn('quit group failed:', error);
|
||||
// Toast({
|
||||
// message: TUITranslateService.t('TUIContact.退出群组失败'),
|
||||
// type: TOAST_TYPE.ERROR,
|
||||
// });
|
||||
// });
|
||||
}
|
||||
|
||||
// Join group
|
||||
export const joinGroup = (groupID: string, applyMessage?: string) => {
|
||||
TUIGroupService.joinGroup({
|
||||
groupID,
|
||||
applyMessage,
|
||||
applyMessage
|
||||
} as JoinGroupParams)
|
||||
.then((imResponse: { data: { status?: string } }) => {
|
||||
switch (imResponse?.data?.status) {
|
||||
case TUIChatEngine.TYPES.JOIN_STATUS_WAIT_APPROVAL: // Wait for administrator approval
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.等待管理员同意'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
break;
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
break
|
||||
case TUIChatEngine.TYPES.JOIN_STATUS_SUCCESS: // Join group successfully
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.加群成功'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
break;
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
break
|
||||
case TUIChatEngine.TYPES.JOIN_STATUS_ALREADY_IN_GROUP: // Already in the group
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.您已是群成员'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
break;
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
break
|
||||
default:
|
||||
break;
|
||||
break
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('join group failed:', error);
|
||||
console.warn('join group failed:', error)
|
||||
Toast({
|
||||
message: '申请入群失败',
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
});
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Add to blacklist
|
||||
export const addToBlacklist = (userID: string, successCallBack?: () => void) => {
|
||||
export const addToBlacklist = (
|
||||
userID: string,
|
||||
successCallBack?: () => void
|
||||
) => {
|
||||
TUIUserService.addToBlacklist({
|
||||
userIDList: [userID],
|
||||
userIDList: [userID]
|
||||
})
|
||||
.then(() => {
|
||||
successCallBack && successCallBack();
|
||||
successCallBack && successCallBack()
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('add to blacklist failed:', error);
|
||||
console.warn('add to blacklist failed:', error)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.加入黑名单失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
});
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Remove from Blacklist
|
||||
export const removeFromBlacklist = (
|
||||
userID: string,
|
||||
successCallBack?: () => void,
|
||||
successCallBack?: () => void
|
||||
) => {
|
||||
TUIUserService.removeFromBlacklist({
|
||||
userIDList: [userID],
|
||||
userIDList: [userID]
|
||||
})
|
||||
.then(() => {
|
||||
successCallBack && successCallBack();
|
||||
successCallBack && successCallBack()
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.warn('remove from blacklist failed:', error);
|
||||
console.warn('remove from blacklist failed:', error)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIContact.移除黑名单失败'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
});
|
||||
};
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<label class="group-list-item-label">
|
||||
{{ TUITranslateService.t('TUIGroup.群头像') }}
|
||||
</label>
|
||||
<Avatar :url="groupInfo.profile.avatar" />
|
||||
<Avatar :url="groupAvatar" @click="selectAvatar" />
|
||||
</li>
|
||||
<ul>
|
||||
<li
|
||||
@@ -158,21 +158,12 @@
|
||||
import Server from '../server'
|
||||
import { IUserProfile } from '../../../interface'
|
||||
import { createImGroup } from '../../../../api/tui-kit'
|
||||
import { chooseImage } from '../../../../utils/media'
|
||||
import { uploadSingleFile } from '../../../../utils/uploadFile'
|
||||
|
||||
const TUIGroupServer = Server.getInstance()
|
||||
const TUIConstants = TUIGroupServer.constants
|
||||
|
||||
/** 自定义数据 */
|
||||
const cbPopupShow = ref(null)
|
||||
const applyJoinOption = ref('NeedPermission')
|
||||
|
||||
const applyJoinOptionName = computed(() => {
|
||||
const data = groupJoinTypeConfig.find(
|
||||
v => v.value === applyJoinOption.value
|
||||
)
|
||||
return data?.label || ''
|
||||
})
|
||||
// =======
|
||||
const groupInfo = reactive<any>({
|
||||
profile: {
|
||||
groupID: '',
|
||||
@@ -195,6 +186,19 @@
|
||||
isEdit: false
|
||||
})
|
||||
|
||||
/** 自定义数据 */
|
||||
const cbPopupShow = ref(null)
|
||||
const applyJoinOption = ref('NeedPermission')
|
||||
// 群头像
|
||||
const groupAvatar = ref(groupInfo.profile.avatar)
|
||||
const applyJoinOptionName = computed(() => {
|
||||
const data = groupJoinTypeConfig.find(
|
||||
v => v.value === applyJoinOption.value
|
||||
)
|
||||
return data?.label || ''
|
||||
})
|
||||
// =======
|
||||
|
||||
watchEffect(() => {
|
||||
const params = TUIGroupServer.getOnCallParams(
|
||||
TUIConstants.TUIGroup.SERVICE.METHOD.CREATE_GROUP
|
||||
@@ -247,35 +251,69 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** 选择群头像 */
|
||||
const selectAvatar = async () => {
|
||||
const paths = await chooseImage({ count: 1 })
|
||||
groupAvatar.value = await uploadSingleFile(paths[0], {
|
||||
url: '/api/common/admin/upload/up/single'
|
||||
})
|
||||
}
|
||||
|
||||
const createGroup = async (options: any) => {
|
||||
console.log('确认创建==', options)
|
||||
// const data = {
|
||||
// currentMemberCount:
|
||||
// }
|
||||
// createImGroup()
|
||||
return
|
||||
try {
|
||||
options.memberList = options.memberList.map(
|
||||
(item: IUserProfile) => {
|
||||
return { userID: item.userID }
|
||||
}
|
||||
)
|
||||
if (options.type === TUIChatEngine.TYPES.GRP_COMMUNITY) {
|
||||
delete options.groupID
|
||||
}
|
||||
const res = await TUIGroupService.createGroup(options)
|
||||
const { type } = res.data.group
|
||||
if (type === TUIChatEngine.TYPES.GRP_AVCHATROOM) {
|
||||
await TUIGroupService.joinGroup({
|
||||
groupID: res.data.group.groupID,
|
||||
applyMessage: ''
|
||||
const data = {
|
||||
applyJoinOption: applyJoinOption.value,
|
||||
faceUrl: groupAvatar.value,
|
||||
groupName: options.name,
|
||||
groupType: options.type,
|
||||
memberList: options.memberList.map((item: IUserProfile) => {
|
||||
return { memberAccount: item.userID }
|
||||
})
|
||||
}
|
||||
handleCompleteCreate(res.data.group)
|
||||
|
||||
const res = await createImGroup(data)
|
||||
const e = res.data
|
||||
// const type = e.groupType
|
||||
// if (type === TUIChatEngine.TYPES.GRP_AVCHATROOM) {
|
||||
// await TUIGroupService.joinGroup({
|
||||
// groupID: e.groupID,
|
||||
// applyMessage: ''
|
||||
// })
|
||||
// }
|
||||
|
||||
const newRes = await TUIGroupService.getGroupProfile({
|
||||
groupID: e.groupId
|
||||
})
|
||||
|
||||
handleCompleteCreate(newRes.data.group)
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIGroup.群组创建成功'),
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
|
||||
// ========= 原本逻辑
|
||||
// options.memberList = options.memberList.map(
|
||||
// (item: IUserProfile) => {
|
||||
// return { userID: item.userID }
|
||||
// }
|
||||
// )
|
||||
// if (options.type === TUIChatEngine.TYPES.GRP_COMMUNITY) {
|
||||
// delete options.groupID
|
||||
// }
|
||||
// const res = await TUIGroupService.createGroup(options)
|
||||
// console.log(res)
|
||||
// const { type } = res.data.group
|
||||
// if (type === TUIChatEngine.TYPES.GRP_AVCHATROOM) {
|
||||
// await TUIGroupService.joinGroup({
|
||||
// groupID: res.data.group.groupID,
|
||||
// applyMessage: ''
|
||||
// })
|
||||
// }
|
||||
// handleCompleteCreate(res.data.group)
|
||||
// Toast({
|
||||
// message: TUITranslateService.t('TUIGroup.群组创建成功'),
|
||||
// type: TOAST_TYPE.SUCCESS
|
||||
// })
|
||||
} catch (err: any) {
|
||||
Toast({
|
||||
message: err.message,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,10 @@
|
||||
<div class="group-info" @click="toggleEditStatus">
|
||||
<Avatar
|
||||
useSkeletonAnimation
|
||||
:url="groupProfile.avatar ||
|
||||
'https://web.sdk.qcloud.com/im/demo/TUIkit/web/img/constomer.svg'"
|
||||
:url="
|
||||
groupProfile.avatar ||
|
||||
'https://web.sdk.qcloud.com/im/demo/TUIkit/web/img/constomer.svg'
|
||||
"
|
||||
size="40px"
|
||||
/>
|
||||
<div class="group-details">
|
||||
@@ -16,28 +18,26 @@
|
||||
<div
|
||||
v-if="isEdit"
|
||||
:class="{
|
||||
'edit-h5': isMobile,
|
||||
'edit-h5': isMobile
|
||||
}"
|
||||
>
|
||||
<main class="edit-h5-main">
|
||||
<header
|
||||
v-if="!isPC"
|
||||
class="edit-h5-header"
|
||||
>
|
||||
<header v-if="!isPC" class="edit-h5-header">
|
||||
<aside class="left">
|
||||
<h1 class="title">{{ TUITranslateService.t(`TUIGroup.修改群聊名称`) }}</h1>
|
||||
<span class="subtitle">{{
|
||||
TUITranslateService.t(
|
||||
`TUIGroup.修改群聊名称后,将在群内通知其他成员`
|
||||
)
|
||||
}}</span>
|
||||
<h1 class="title">
|
||||
{{ TUITranslateService.t(`TUIGroup.修改群聊名称`) }}
|
||||
</h1>
|
||||
<span class="subtitle">
|
||||
{{
|
||||
TUITranslateService.t(
|
||||
`TUIGroup.修改群聊名称后,将在群内通知其他成员`
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</aside>
|
||||
<span
|
||||
class="close"
|
||||
@click="toggleEditStatus"
|
||||
>{{
|
||||
TUITranslateService.t(`关闭`)
|
||||
}}</span>
|
||||
<span class="close" @click="toggleEditStatus">
|
||||
{{ TUITranslateService.t(`关闭`) }}
|
||||
</span>
|
||||
</header>
|
||||
<div class="input-box">
|
||||
<input
|
||||
@@ -46,24 +46,17 @@
|
||||
v-model="inputGroupName"
|
||||
class="input"
|
||||
type="text"
|
||||
>
|
||||
<span
|
||||
v-if="!isPC"
|
||||
class="tip"
|
||||
>{{
|
||||
TUITranslateService.t(
|
||||
`TUIGroup.仅限中文、字母、数字和下划线,2-20个字`
|
||||
)
|
||||
}}</span>
|
||||
/>
|
||||
<span v-if="!isPC" class="tip">
|
||||
{{
|
||||
TUITranslateService.t(
|
||||
`TUIGroup.仅限中文、字母、数字和下划线,2-20个字`
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<footer
|
||||
v-if="!isPC"
|
||||
class="edit-h5-footer"
|
||||
>
|
||||
<button
|
||||
class="btn"
|
||||
@click="updateProfile"
|
||||
>
|
||||
<footer v-if="!isPC" class="edit-h5-footer">
|
||||
<button class="btn" @click="updateProfile">
|
||||
{{ TUITranslateService.t(`确认`) }}
|
||||
</button>
|
||||
</footer>
|
||||
@@ -73,226 +66,226 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { watchEffect, ref, nextTick, watch } from '../../../adapter-vue';
|
||||
import {
|
||||
TUITranslateService,
|
||||
IGroupModel,
|
||||
} from '@tencentcloud/chat-uikit-engine-lite';
|
||||
import Avatar from "../../common/Avatar/index.vue";
|
||||
import Icon from '../../common/Icon.vue';
|
||||
import rightIcon from '../../../assets/icon/right-icon.svg';
|
||||
import { Toast, TOAST_TYPE } from '../../common/Toast/index';
|
||||
import { isMobile, isPC } from '../../../utils/env';
|
||||
import { watchEffect, ref, nextTick, watch } from '../../../adapter-vue'
|
||||
import {
|
||||
TUITranslateService,
|
||||
IGroupModel
|
||||
} from '@tencentcloud/chat-uikit-engine-lite'
|
||||
import Avatar from '../../common/Avatar/index.vue'
|
||||
import Icon from '../../common/Icon.vue'
|
||||
import rightIcon from '../../../assets/icon/right-icon.svg'
|
||||
import { Toast, TOAST_TYPE } from '../../common/Toast/index'
|
||||
import { isMobile, isPC } from '../../../utils/env'
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
isAuthor: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
isAuthor: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const groupProfile = ref<IGroupModel>({});
|
||||
const inputGroupName = ref('');
|
||||
const isEdit = ref(false);
|
||||
const nameInputRef = ref<HTMLInputElement>(null);
|
||||
const groupProfile = ref<IGroupModel>({})
|
||||
const inputGroupName = ref('')
|
||||
const isEdit = ref(false)
|
||||
const nameInputRef = ref<HTMLInputElement>(null)
|
||||
|
||||
watchEffect(() => {
|
||||
groupProfile.value = props.data;
|
||||
});
|
||||
watchEffect(() => {
|
||||
groupProfile.value = props.data
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update']);
|
||||
const updateProfile = () => {
|
||||
if (!inputGroupName.value) {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIGroup.群名称不能为空'),
|
||||
type: TOAST_TYPE.ERROR,
|
||||
});
|
||||
} else {
|
||||
if (inputGroupName.value !== groupProfile.value.name) {
|
||||
emit('update', { key: 'name', value: inputGroupName.value });
|
||||
groupProfile.value.name = inputGroupName.value;
|
||||
inputGroupName.value = '';
|
||||
const emit = defineEmits(['update'])
|
||||
const updateProfile = () => {
|
||||
if (!inputGroupName.value) {
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIGroup.群名称修改成功'),
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
});
|
||||
message: TUITranslateService.t('TUIGroup.群名称不能为空'),
|
||||
type: TOAST_TYPE.ERROR
|
||||
})
|
||||
} else {
|
||||
if (inputGroupName.value !== groupProfile.value.name) {
|
||||
emit('update', { key: 'name', value: inputGroupName.value })
|
||||
groupProfile.value.name = inputGroupName.value
|
||||
inputGroupName.value = ''
|
||||
Toast({
|
||||
message: TUITranslateService.t('TUIGroup.群名称修改成功'),
|
||||
type: TOAST_TYPE.SUCCESS
|
||||
})
|
||||
}
|
||||
toggleEditStatus()
|
||||
}
|
||||
toggleEditStatus();
|
||||
}
|
||||
};
|
||||
|
||||
const toggleEditStatus = () => {
|
||||
if (props.isAuthor) {
|
||||
isEdit.value = !isEdit.value;
|
||||
}
|
||||
if (isEdit.value) {
|
||||
inputGroupName.value = groupProfile.value.name;
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => isEdit.value,
|
||||
(newVal: boolean) => {
|
||||
if (newVal) {
|
||||
nextTick(() => {
|
||||
nameInputRef.value?.focus();
|
||||
});
|
||||
const toggleEditStatus = () => {
|
||||
if (props.isAuthor) {
|
||||
isEdit.value = !isEdit.value
|
||||
}
|
||||
},
|
||||
);
|
||||
if (isEdit.value) {
|
||||
inputGroupName.value = groupProfile.value.name
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => isEdit.value,
|
||||
(newVal: boolean) => {
|
||||
if (newVal) {
|
||||
nextTick().then(() => {
|
||||
nameInputRef.value?.focus()
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "../../../assets/styles/common";
|
||||
@import '../../../assets/styles/common';
|
||||
|
||||
.group-name {
|
||||
padding: 14px 20px;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.group-info {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.group-details {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-direction: column;
|
||||
.name {
|
||||
font-size: 16px;
|
||||
line-height: 18px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
}
|
||||
.ID {
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
font-weight: 400;
|
||||
color: #888;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.input-box {
|
||||
display: flex;
|
||||
|
||||
.input {
|
||||
flex: 1;
|
||||
border: 1px solid #e8e8e9;
|
||||
border-radius: 4px;
|
||||
padding: 4px 16px;
|
||||
.group-name {
|
||||
padding: 14px 20px;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
.space-top {
|
||||
border-top: 10px solid #f4f5f9;
|
||||
}
|
||||
|
||||
.edit-h5 {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
z-index: 1;
|
||||
|
||||
.edit-h5-main {
|
||||
background: #fff;
|
||||
flex: 1;
|
||||
padding: 18px;
|
||||
border-radius: 12px 12px 0 0;
|
||||
width: 80vw;
|
||||
|
||||
.input-box {
|
||||
flex-direction: column;
|
||||
padding: 18px 0;
|
||||
|
||||
.input {
|
||||
background: #f8f8f8;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
padding-top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.group-info {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: PingFang SC;
|
||||
.group-details {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-direction: column;
|
||||
.name {
|
||||
font-size: 16px;
|
||||
line-height: 18px;
|
||||
font-weight: 500;
|
||||
font-size: 22px;
|
||||
line-height: 26px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.close {
|
||||
font-family: PingFangSC-Regular;
|
||||
.ID {
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
color: #3370ff;
|
||||
letter-spacing: 0;
|
||||
line-height: 27px;
|
||||
color: #888;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&-footer {
|
||||
.input-box {
|
||||
display: flex;
|
||||
|
||||
.btn {
|
||||
.input {
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: #147aff;
|
||||
border-radius: 5px;
|
||||
font-family: PingFangSC-Regular;
|
||||
border: 1px solid #e8e8e9;
|
||||
border-radius: 4px;
|
||||
padding: 4px 16px;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
letter-spacing: 0;
|
||||
line-height: 27px;
|
||||
padding: 8px 0;
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.3;
|
||||
.space-top {
|
||||
border-top: 10px solid #f4f5f9;
|
||||
}
|
||||
|
||||
.edit-h5 {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
z-index: 1;
|
||||
|
||||
.edit-h5-main {
|
||||
background: #fff;
|
||||
flex: 1;
|
||||
padding: 18px;
|
||||
border-radius: 12px 12px 0 0;
|
||||
width: 80vw;
|
||||
|
||||
.input-box {
|
||||
flex-direction: column;
|
||||
padding: 18px 0;
|
||||
|
||||
.input {
|
||||
background: #f8f8f8;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
padding-top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
h1 {
|
||||
font-family: PingFang SC;
|
||||
font-weight: 500;
|
||||
font-size: 22px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.close {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
color: #3370ff;
|
||||
letter-spacing: 0;
|
||||
line-height: 27px;
|
||||
}
|
||||
}
|
||||
|
||||
&-footer {
|
||||
display: flex;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
border: none;
|
||||
background: #147aff;
|
||||
border-radius: 5px;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
letter-spacing: 0;
|
||||
line-height: 27px;
|
||||
padding: 8px 0;
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user