123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- <template>
- <div
- v-if="typeof contactInfoData === 'object' && Object.keys(contactInfoData).length"
- :class="['tui-contact-info', !isPC && 'tui-contact-info-h5']"
- >
- <div
- v-if="!isPC"
- :class="[
- 'tui-contact-info-header',
- !isPC && 'tui-contact-info-h5-header',
- ]"
- >
- <div
- :class="[
- 'tui-contact-info-header-icon',
- !isPC && 'tui-contact-info-h5-header-icon',
- ]"
- @click="resetContactSearchingUIData"
- >
- <Icon :file="backSVG" />
- </div>
- <div
- :class="[
- 'tui-contact-info-header-title',
- !isPC && 'tui-contact-info-h5-header-title',
- ]"
- >
- {{ TUITranslateService.t("TUIContact.添加好友/群聊") }}
- </div>
- </div>
- <div :class="['tui-contact-info-basic', !isPC && 'tui-contact-info-h5-basic']">
- <div
- :class="[
- 'tui-contact-info-basic-text',
- !isPC && 'tui-contact-info-h5-basic-text',
- ]"
- >
- <div
- :class="[
- 'tui-contact-info-basic-text-name',
- !isPC && 'tui-contact-info-h5-basic-text-name',
- ]"
- >
- {{ generateContactInfoName(contactInfoData) }}
- </div>
- <div
- v-for="item in contactInfoBasicList"
- :key="item.label"
- :class="[
- 'tui-contact-info-basic-text-other',
- !isPC && 'tui-contact-info-h5-basic-text-other',
- ]"
- >
- {{
- `${TUITranslateService.t(`TUIContact.${item.label}`)}:
- ${item.data}`
- }}
- </div>
- </div>
- <img
- :class="[
- 'tui-contact-info-basic-avatar',
- !isPC && 'tui-contact-info-h5-basic-avatar',
- ]"
- :src="generateAvatar(contactInfoData)"
- >
- </div>
- <div
- v-if="contactInfoMoreList[0]"
- :class="['tui-contact-info-more', !isPC && 'tui-contact-info-h5-more']"
- >
- <div
- v-for="item in contactInfoMoreList"
- :key="item.key"
- :class="[
- 'tui-contact-info-more-item',
- !isPC && 'tui-contact-info-h5-more-item',
- item.labelPosition === CONTACT_INFO_LABEL_POSITION.TOP
- ? 'tui-contact-info-more-item-top'
- : 'tui-contact-info-more-item-left',
- ]"
- >
- <div
- :class="[
- 'tui-contact-info-more-item-label',
- !isPC && 'tui-contact-info-h5-more-item-label',
- ]"
- >
- {{ `${TUITranslateService.t(`TUIContact.${item.label}`)}` }}
- </div>
- <div
- :class="[
- 'tui-contact-info-more-item-content',
- !isPC && 'tui-contact-info-h5-more-item-content',
- ]"
- >
- <div
- v-if="!item.editing"
- :class="[
- 'tui-contact-info-more-item-content-text',
- !isPC && 'tui-contact-info-h5-more-item-content-text',
- ]"
- >
- <div
- :class="[
- 'tui-contact-info-more-item-content-text-data',
- !isPC && 'tui-contact-info-h5-more-item-content-text-data',
- ]"
- >
- {{ item.data }}
- </div>
- <div
- v-if="item.editable"
- :class="[
- 'tui-contact-info-more-item-content-text-icon',
- !isPC && 'tui-contact-info-h5-more-item-content-text-icon',
- ]"
- @click="setEditing(item)"
- >
- <Icon
- :file="editSVG"
- width="14px"
- height="14px"
- />
- </div>
- </div>
- <input
- v-else-if="item.editType === CONTACT_INFO_MORE_EDIT_TYPE.INPUT"
- v-model="item.data"
- :class="[
- 'tui-contact-info-more-item-content-input',
- !isPC && 'tui-contact-info-h5-more-item-content-input',
- ]"
- type="text"
- @confirm="onContactInfoEmitSubmit(item)"
- @keyup.enter="onContactInfoEmitSubmit(item)"
- >
- <textarea
- v-else-if="item.editType === CONTACT_INFO_MORE_EDIT_TYPE.TEXTAREA"
- v-model="item.data"
- :class="[
- 'tui-contact-info-more-item-content-textarea',
- !isPC && 'tui-contact-info-h5-more-item-content-textarea',
- ]"
- confirm-type="done"
- />
- <div
- v-else-if="item.editType === CONTACT_INFO_MORE_EDIT_TYPE.SWITCH"
- @click="onContactInfoEmitSubmit(item)"
- >
- <SwitchBar :value="item.data" />
- </div>
- </div>
- </div>
- </div>
- <div
- :class="[
- 'tui-contact-info-button',
- !isPC && 'tui-contact-info-h5-button',
- ]"
- >
- <button
- v-for="item in contactInfoButtonList"
- :key="item.key"
- :class="[
- 'tui-contact-info-button-item',
- !isPC && 'tui-contact-info-h5-button-item',
- item.type === CONTACT_INFO_BUTTON_TYPE.CANCEL
- ? `tui-contact-info-button-item-cancel`
- : `tui-contact-info-button-item-submit`,
- ]"
- @click="onContactInfoButtonClicked(item)"
- >
- {{ TUITranslateService.t(`TUIContact.${item.label}`) }}
- </button>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import TUIChatEngine, {
- TUIStore,
- StoreName,
- TUITranslateService,
- IGroupModel,
- Friend,
- FriendApplication,
- } from '@tencentcloud/chat-uikit-engine';
- import { TUIGlobal } from '@tencentcloud/universal-api';
- import { ref, computed, onMounted, onUnmounted } from '../../../adapter-vue';
- import { isPC } from '../../../utils/env';
- import {
- generateAvatar,
- generateContactInfoName,
- generateContactInfoBasic,
- isFriend,
- isApplicationType,
- } from '../utils/index';
- import {
- contactMoreInfoConfig,
- contactButtonConfig,
- } from './contact-info-config';
- import Icon from '../../common/Icon.vue';
- import editSVG from '../../../assets/icon/edit.svg';
- import backSVG from '../../../assets/icon/back.svg';
- import SwitchBar from '../../common/SwitchBar/index.vue';
- import {
- IBlackListUserItem,
- IContactInfoMoreItem,
- IContactInfoButton,
- } from '../../../interface';
- import {
- CONTACT_INFO_LABEL_POSITION,
- CONTACT_INFO_MORE_EDIT_TYPE,
- CONTACT_INFO_BUTTON_TYPE,
- } from '../../../constant';
- import { deepCopy } from '../../TUIChat/utils/utils';
- type IContactInfoType = IGroupModel | Friend | FriendApplication | IBlackListUserItem;
- const emits = defineEmits(['switchConversation']);
- const contactInfoData = ref<IContactInfoType>({} as IContactInfoType);
- const contactInfoBasicList = ref<Array<{ label: string; data: string }>>([]);
- const contactInfoMoreList = ref<IContactInfoMoreItem[]>([]);
- const contactInfoButtonList = ref<IContactInfoButton[]>([]);
- const setEditing = (item: any) => {
- item.editing = true;
- };
- const isGroup = computed((): boolean =>
- (contactInfoData.value as IGroupModel)?.groupID ? true : false,
- );
- const isApplication = computed((): boolean => {
- return isApplicationType(contactInfoData?.value);
- });
- // is both friend, if is group type always false
- const isBothFriend = ref<boolean>(false);
- // is group member, including ordinary member, admin, group owner
- const isGroupMember = computed((): boolean => {
- return (contactInfoData.value as IGroupModel)?.selfInfo?.userID ? true : false;
- });
- // is in black list, if is group type always false
- const isInBlackList = computed((): boolean => {
- return (
- !isGroup.value
- && blackList.value?.findIndex(
- (item: IBlackListUserItem) =>
- item?.userID === (contactInfoData.value as IBlackListUserItem)?.userID,
- ) >= 0
- );
- });
- const blackList = ref<IBlackListUserItem[]>([]);
- onMounted(() => {
- TUIStore.watch(StoreName.CUSTOM, {
- currentContactInfo: onCurrentContactInfoUpdated,
- });
- TUIStore.watch(StoreName.USER, {
- userBlacklist: onUserBlacklistUpdated,
- });
- });
- onUnmounted(() => {
- TUIStore.unwatch(StoreName.CUSTOM, {
- currentContactInfo: onCurrentContactInfoUpdated,
- });
- TUIStore.unwatch(StoreName.USER, {
- userBlacklist: onUserBlacklistUpdated,
- });
- });
- const resetContactInfoUIData = () => {
- contactInfoData.value = {} as IContactInfoType;
- contactInfoBasicList.value = [];
- contactInfoMoreList.value = [];
- contactInfoButtonList.value = [];
- };
- const resetContactSearchingUIData = () => {
- TUIStore.update(StoreName.CUSTOM, 'currentContactInfo', {});
- TUIStore.update(StoreName.CUSTOM, 'currentContactSearchingStatus', false);
- TUIGlobal?.closeSearching && TUIGlobal?.closeSearching();
- };
- const onContactInfoEmitSubmit = (item: any) => {
- item.editSubmitHandler
- && item.editSubmitHandler({
- item,
- contactInfoData: contactInfoData.value,
- isBothFriend: isBothFriend.value,
- isInBlackList: isInBlackList.value,
- });
- };
- const onContactInfoButtonClicked = (item: any) => {
- item.onClick
- && item.onClick({
- contactInfoData: contactInfoData.value,
- contactInfoMoreList: contactInfoMoreList.value,
- });
- if (
- item.key === 'enterGroupConversation'
- || item.key === 'enterC2CConversation'
- ) {
- emits('switchConversation', contactInfoData.value);
- resetContactSearchingUIData();
- }
- };
- const generateMoreInfo = async () => {
- if (!isApplication.value) {
- if (
- (!isGroup.value && !isBothFriend.value && !isInBlackList.value)
- || (isGroup.value
- && !isGroupMember.value
- && (contactInfoData.value as IGroupModel)?.type !== TUIChatEngine?.TYPES?.GRP_AVCHATROOM)
- ) {
- contactMoreInfoConfig.setWords.data = '';
- contactInfoMoreList.value.push(contactMoreInfoConfig.setWords);
- }
- if (!isGroup.value && !isInBlackList.value) {
- contactMoreInfoConfig.setRemark.data
- = (contactInfoData.value as Friend)?.remark || '';
- contactMoreInfoConfig.setRemark.editing = false;
- contactInfoMoreList.value.push(contactMoreInfoConfig.setRemark);
- }
- if (!isGroup.value && (isBothFriend.value || isInBlackList.value)) {
- contactMoreInfoConfig.blackList.data = isInBlackList.value || false;
- contactInfoMoreList.value.push(contactMoreInfoConfig.blackList);
- }
- } else {
- contactMoreInfoConfig.displayWords.data
- = (contactInfoData.value as FriendApplication)?.wording || '';
- contactInfoMoreList.value.push(contactMoreInfoConfig.displayWords);
- }
- };
- const generateButton = () => {
- if (isInBlackList.value) {
- return;
- }
- if (isApplication.value) {
- if (
- (contactInfoData.value as FriendApplication)?.type
- === TUIChatEngine?.TYPES?.SNS_APPLICATION_SENT_TO_ME
- ) {
- contactInfoButtonList?.value?.push(
- contactButtonConfig.refuseFriendApplication,
- );
- contactInfoButtonList?.value?.push(
- contactButtonConfig.acceptFriendApplication,
- );
- }
- } else {
- if (isGroup.value && isGroupMember.value) {
- switch ((contactInfoData.value as IGroupModel)?.selfInfo?.role) {
- case 'Owner':
- contactInfoButtonList?.value?.push(contactButtonConfig.dismissGroup);
- break;
- default:
- contactInfoButtonList?.value?.push(contactButtonConfig.quitGroup);
- break;
- }
- contactInfoButtonList?.value?.push(
- contactButtonConfig.enterGroupConversation,
- );
- } else if (!isGroup.value && isBothFriend.value) {
- contactInfoButtonList?.value?.push(contactButtonConfig.deleteFriend);
- contactInfoButtonList?.value?.push(
- contactButtonConfig.enterC2CConversation,
- );
- } else {
- if (isGroup.value) {
- contactInfoButtonList?.value?.push(
- (contactInfoData.value as IGroupModel)?.type === TUIChatEngine?.TYPES?.GRP_AVCHATROOM
- ? contactButtonConfig.joinAVChatGroup
- : contactButtonConfig.joinGroup,
- );
- } else {
- contactInfoButtonList?.value?.push(contactButtonConfig.addFriend);
- }
- }
- }
- };
- function onUserBlacklistUpdated(userBlacklist: IBlackListUserItem[]) {
- blackList.value = userBlacklist;
- }
- async function onCurrentContactInfoUpdated(contactInfo: IContactInfoType) {
- if (
- contactInfoData.value
- && contactInfo
- && JSON.stringify(contactInfoData.value) === JSON.stringify(contactInfo)
- ) {
- return;
- }
- resetContactInfoUIData();
- // deep clone
- contactInfoData.value = deepCopy(contactInfo) || {};
- if (!contactInfoData.value || Object.keys(contactInfoData.value)?.length === 0) {
- return;
- }
- contactInfoBasicList.value = generateContactInfoBasic(
- contactInfoData.value,
- );
- isBothFriend.value = await isFriend(contactInfoData.value);
- generateMoreInfo();
- generateButton();
- if (contactInfo.infoKeyList) {
- contactInfoMoreList.value = contactInfo.infoKeyList.map((key: string) => {
- return (contactMoreInfoConfig as any)[key];
- });
- }
- if (contactInfo.btnKeyList) {
- contactInfoButtonList.value = contactInfo.btnKeyList.map((key: string) => {
- return (contactButtonConfig as any)[key];
- });
- }
- }
- </script>
- <style lang="scss" scoped src="./style/index.scss"></style>
|