添加聊天
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import imageIconLight from '../../../../assets/icon/image-light.svg';
|
||||
import imageIconDark from '../../../../assets/icon/image-dark.svg';
|
||||
import imageUniIcon from '../../../../assets/icon/image-uni.png';
|
||||
import cameraUniIcon from '../../../../assets/icon/camera-uni.png';
|
||||
import videoIconLight from '../../../../assets/icon/video-light.svg';
|
||||
import videoIconDark from '../../../../assets/icon/video-dark.svg';
|
||||
import videoUniIcon from '../../../../assets/icon/video-uni.png';
|
||||
import fileIconLight from '../../../../assets/icon/file-light.svg';
|
||||
import fileIconDark from '../../../../assets/icon/file-dark.svg';
|
||||
|
||||
export const ICON_SIZE_CONFIG = {
|
||||
WEB: {
|
||||
WIDTH: '20px',
|
||||
HEIGHT: '18px',
|
||||
},
|
||||
UNI: {
|
||||
WIDTH: '32px',
|
||||
HEIGHT: '25px',
|
||||
},
|
||||
};
|
||||
|
||||
export const TOOLBAR_ICON_MAP = {
|
||||
IMAGE_WEB_LIGHT: imageIconLight,
|
||||
IMAGE_WEB_DARK: imageIconDark,
|
||||
IMAGE_UNI: imageUniIcon,
|
||||
CAMERA_UNI: cameraUniIcon,
|
||||
VIDEO_WEB_LIGHT: videoIconLight,
|
||||
VIDEO_WEB_DARK: videoIconDark,
|
||||
VIDEO_UNI: videoUniIcon,
|
||||
FILE_WEB_LIGHT: fileIconLight,
|
||||
FILE_WEB_DARK: fileIconDark,
|
||||
};
|
||||
|
||||
export enum UploadType {
|
||||
IMAGE = 'IMAGE',
|
||||
VIDEO = 'VIDEO',
|
||||
FILE = 'FILE',
|
||||
ALBUM = 'ALBUM',
|
||||
CAMERA = 'CAMERA',
|
||||
}
|
||||
|
||||
export enum SourceType {
|
||||
ALBUM = 'album',
|
||||
CAMERA = 'camera',
|
||||
}
|
||||
|
||||
export enum PlatformType {
|
||||
WEB = 'WEB',
|
||||
UNI = 'UNI',
|
||||
}
|
||||
|
||||
export enum ThemeType {
|
||||
LIGHT = 'light',
|
||||
DARK = 'dark',
|
||||
}
|
||||
|
||||
export enum MediaType {
|
||||
IMAGE = 'image',
|
||||
VIDEO = 'video',
|
||||
FILE = 'file',
|
||||
}
|
||||
|
||||
export enum ToolbarTitle {
|
||||
IMAGE = '图片',
|
||||
PHOTO = '照片',
|
||||
VIDEO = '视频',
|
||||
FILE = '文件',
|
||||
CAMERA = '拍照',
|
||||
RECORD = '录制',
|
||||
SHOOT = '拍摄',
|
||||
}
|
||||
|
||||
export const TOOLBAR_DISPLAY_CONFIG = {
|
||||
[UploadType.IMAGE]: {
|
||||
[PlatformType.WEB]: {
|
||||
title: ToolbarTitle.IMAGE,
|
||||
getIcon: (theme: string) => theme === ThemeType.DARK ? TOOLBAR_ICON_MAP.IMAGE_WEB_DARK : TOOLBAR_ICON_MAP.IMAGE_WEB_LIGHT,
|
||||
},
|
||||
[PlatformType.UNI]: {
|
||||
title: ToolbarTitle.PHOTO,
|
||||
icon: TOOLBAR_ICON_MAP.IMAGE_UNI,
|
||||
},
|
||||
},
|
||||
|
||||
[UploadType.VIDEO]: {
|
||||
[PlatformType.WEB]: {
|
||||
title: ToolbarTitle.VIDEO,
|
||||
getIcon: (theme: string) => theme === ThemeType.DARK ? TOOLBAR_ICON_MAP.VIDEO_WEB_DARK : TOOLBAR_ICON_MAP.VIDEO_WEB_LIGHT,
|
||||
},
|
||||
[PlatformType.UNI]: {
|
||||
title: ToolbarTitle.VIDEO,
|
||||
icon: TOOLBAR_ICON_MAP.VIDEO_UNI,
|
||||
},
|
||||
},
|
||||
|
||||
[UploadType.FILE]: {
|
||||
[PlatformType.WEB]: {
|
||||
title: ToolbarTitle.FILE,
|
||||
getIcon: (theme: string) => theme === ThemeType.DARK ? TOOLBAR_ICON_MAP.FILE_WEB_DARK : TOOLBAR_ICON_MAP.FILE_WEB_LIGHT,
|
||||
},
|
||||
},
|
||||
|
||||
[UploadType.ALBUM]: {
|
||||
[PlatformType.UNI]: {
|
||||
title: ToolbarTitle.PHOTO,
|
||||
icon: TOOLBAR_ICON_MAP.IMAGE_UNI,
|
||||
},
|
||||
},
|
||||
|
||||
[UploadType.CAMERA]: {
|
||||
[PlatformType.UNI]: {
|
||||
title: ToolbarTitle.SHOOT,
|
||||
icon: TOOLBAR_ICON_MAP.CAMERA_UNI,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const MEDIA_CHOOSE_CONFIG = {
|
||||
IMAGE: {
|
||||
COUNT: 1,
|
||||
MEDIA_TYPE: [MediaType.IMAGE],
|
||||
SIZE_TYPE: ['original', 'compressed'],
|
||||
},
|
||||
VIDEO: {
|
||||
COUNT: 1,
|
||||
MEDIA_TYPE: [MediaType.VIDEO],
|
||||
MAX_DURATION: 60,
|
||||
COMPRESSED: false,
|
||||
},
|
||||
MIXED: {
|
||||
COUNT: 1,
|
||||
MEDIA_TYPE: [MediaType.IMAGE, MediaType.VIDEO],
|
||||
SIZE_TYPE: ['original', 'compressed'],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
export { useUpload, genSourceType } from './useUpload';
|
||||
export {
|
||||
UploadType,
|
||||
SourceType,
|
||||
PlatformType,
|
||||
ThemeType,
|
||||
MediaType,
|
||||
ToolbarTitle,
|
||||
} from './constants';
|
||||
export * from './constants';
|
||||
export * from './utils';
|
||||
@@ -0,0 +1,183 @@
|
||||
import { ref, computed } from '../../../../adapter-vue';
|
||||
import { TUIStore, StoreName, IConversationModel } from '@tencentcloud/chat-uikit-engine-lite';
|
||||
import { TUIGlobal } from '@tencentcloud/universal-api';
|
||||
import { isPC, isUniFrameWork } from '../../../../utils/env';
|
||||
import TUIChatConfig from '../../config';
|
||||
import {
|
||||
TOOLBAR_DISPLAY_CONFIG,
|
||||
ICON_SIZE_CONFIG,
|
||||
MEDIA_CHOOSE_CONFIG,
|
||||
UploadType,
|
||||
SourceType,
|
||||
PlatformType,
|
||||
} from './constants';
|
||||
import {
|
||||
sendImageMessage,
|
||||
sendVideoMessage,
|
||||
sendFileMessage,
|
||||
handleWebFileSelect,
|
||||
} from './utils';
|
||||
|
||||
export function genSourceType(uploadType: UploadType): SourceType {
|
||||
if (uploadType === UploadType.CAMERA) {
|
||||
return SourceType.CAMERA;
|
||||
}
|
||||
return SourceType.ALBUM;
|
||||
}
|
||||
|
||||
export function useUpload(uploadType: UploadType) {
|
||||
const inputRef = ref();
|
||||
const currentConversation = ref<IConversationModel>();
|
||||
const theme = TUIChatConfig.getTheme();
|
||||
|
||||
TUIStore.watch(StoreName.CONV, {
|
||||
currentConversation: (conversation: IConversationModel) => {
|
||||
currentConversation.value = conversation;
|
||||
},
|
||||
});
|
||||
|
||||
const sourceType = genSourceType(uploadType);
|
||||
|
||||
const toolbarConfig = computed(() => {
|
||||
const config = TOOLBAR_DISPLAY_CONFIG[uploadType];
|
||||
|
||||
if (isUniFrameWork) {
|
||||
const displayConfig = (config as any)[PlatformType.UNI];
|
||||
|
||||
return {
|
||||
icon: displayConfig.icon,
|
||||
title: displayConfig.title,
|
||||
iconWidth: ICON_SIZE_CONFIG.UNI.WIDTH,
|
||||
iconHeight: ICON_SIZE_CONFIG.UNI.HEIGHT,
|
||||
};
|
||||
} else {
|
||||
const displayConfig = (config as any)[PlatformType.WEB];
|
||||
|
||||
return {
|
||||
icon: displayConfig.getIcon ? displayConfig.getIcon(theme) : displayConfig.icon,
|
||||
title: displayConfig.title,
|
||||
iconWidth: ICON_SIZE_CONFIG.WEB.WIDTH,
|
||||
iconHeight: ICON_SIZE_CONFIG.WEB.HEIGHT,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const handleIconClick = () => {
|
||||
if (isUniFrameWork) {
|
||||
handleUniAppClick();
|
||||
} else {
|
||||
handleWebClick();
|
||||
}
|
||||
};
|
||||
|
||||
const handleUniAppClick = () => {
|
||||
switch (uploadType) {
|
||||
case UploadType.IMAGE:
|
||||
chooseImageInUniApp();
|
||||
break;
|
||||
case UploadType.VIDEO:
|
||||
chooseVideoInUniApp();
|
||||
break;
|
||||
case UploadType.ALBUM:
|
||||
chooseMediaInUniApp();
|
||||
break;
|
||||
case UploadType.CAMERA:
|
||||
chooseCameraInUniApp();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const handleWebClick = () => {
|
||||
if (inputRef.value?.click) {
|
||||
inputRef.value.click();
|
||||
}
|
||||
};
|
||||
|
||||
const chooseImageInUniApp = () => {
|
||||
TUIGlobal?.chooseImage({
|
||||
count: MEDIA_CHOOSE_CONFIG.IMAGE.COUNT,
|
||||
sourceType: [sourceType],
|
||||
success: function (res: Record<string, any>) {
|
||||
if (currentConversation.value) {
|
||||
sendImageMessage(currentConversation.value, res);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const chooseVideoInUniApp = () => {
|
||||
TUIGlobal?.chooseVideo({
|
||||
count: MEDIA_CHOOSE_CONFIG.VIDEO.COUNT,
|
||||
sourceType: [sourceType],
|
||||
compressed: MEDIA_CHOOSE_CONFIG.VIDEO.COMPRESSED,
|
||||
success: function (res: Record<string, any>) {
|
||||
if (currentConversation.value) {
|
||||
sendVideoMessage(currentConversation.value, res);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const chooseMediaInUniApp = () => {
|
||||
TUIGlobal?.chooseImage({
|
||||
count: MEDIA_CHOOSE_CONFIG.IMAGE.COUNT,
|
||||
sourceType: [SourceType.ALBUM, SourceType.CAMERA],
|
||||
success: function (res: Record<string, any>) {
|
||||
if (currentConversation.value) {
|
||||
sendImageMessage(currentConversation.value, res);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const chooseCameraInUniApp = () => {
|
||||
TUIGlobal?.chooseVideo({
|
||||
count: MEDIA_CHOOSE_CONFIG.VIDEO.COUNT,
|
||||
sourceType: [SourceType.ALBUM, SourceType.CAMERA],
|
||||
compressed: MEDIA_CHOOSE_CONFIG.VIDEO.COMPRESSED,
|
||||
success: function (res: Record<string, any>) {
|
||||
if (currentConversation.value) {
|
||||
sendVideoMessage(currentConversation.value, res);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleWebFileChange = (event: Event) => {
|
||||
switch (uploadType) {
|
||||
case UploadType.IMAGE:
|
||||
handleWebFileSelect(event, (file) => {
|
||||
if (currentConversation.value) {
|
||||
sendImageMessage(currentConversation.value, file);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case UploadType.VIDEO:
|
||||
handleWebFileSelect(event, (file) => {
|
||||
if (currentConversation.value) {
|
||||
sendVideoMessage(currentConversation.value, file);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case UploadType.FILE:
|
||||
handleWebFileSelect(event, (file) => {
|
||||
if (currentConversation.value) {
|
||||
sendFileMessage(currentConversation.value, file);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
inputRef,
|
||||
currentConversation,
|
||||
toolbarConfig,
|
||||
isPC,
|
||||
isUniFrameWork,
|
||||
handleIconClick,
|
||||
handleWebFileChange,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import TUIChatEngine, {
|
||||
TUIChatService,
|
||||
IConversationModel,
|
||||
SendMessageParams,
|
||||
SendMessageOptions,
|
||||
} from '@tencentcloud/chat-uikit-engine-lite';
|
||||
import { isEnabledMessageReadReceiptGlobal } from '../../utils/utils';
|
||||
import OfflinePushInfoManager, { IOfflinePushInfoCreateParams } from '../../offlinePushInfoManager/index';
|
||||
|
||||
export function createSendMessageOptions(
|
||||
currentConversation: IConversationModel | undefined,
|
||||
file: any,
|
||||
): SendMessageParams {
|
||||
return {
|
||||
to:
|
||||
currentConversation?.groupProfile?.groupID
|
||||
|| currentConversation?.userProfile?.userID,
|
||||
conversationType: currentConversation?.type,
|
||||
payload: {
|
||||
file,
|
||||
},
|
||||
needReadReceipt: isEnabledMessageReadReceiptGlobal(),
|
||||
} as SendMessageParams;
|
||||
}
|
||||
|
||||
export function genOfflinePushInfo(
|
||||
currentConversation: IConversationModel,
|
||||
payload: any,
|
||||
messageType: any,
|
||||
): SendMessageOptions {
|
||||
const offlinePushInfoCreateParams: IOfflinePushInfoCreateParams = {
|
||||
conversation: currentConversation,
|
||||
payload,
|
||||
messageType,
|
||||
};
|
||||
|
||||
return {
|
||||
offlinePushInfo: OfflinePushInfoManager.create(offlinePushInfoCreateParams),
|
||||
};
|
||||
}
|
||||
|
||||
export function sendImageMessage(
|
||||
currentConversation: IConversationModel,
|
||||
files: any,
|
||||
): void {
|
||||
if (!files) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options = createSendMessageOptions(currentConversation, files);
|
||||
const sendMessageOptions = genOfflinePushInfo(
|
||||
currentConversation,
|
||||
options.payload,
|
||||
TUIChatEngine.TYPES.MSG_IMAGE,
|
||||
);
|
||||
|
||||
TUIChatService.sendImageMessage(options, sendMessageOptions);
|
||||
}
|
||||
|
||||
export function sendVideoMessage(
|
||||
currentConversation: IConversationModel,
|
||||
file: any,
|
||||
): void {
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options = createSendMessageOptions(currentConversation, file);
|
||||
const sendMessageOptions = genOfflinePushInfo(
|
||||
currentConversation,
|
||||
options.payload,
|
||||
TUIChatEngine.TYPES.MSG_VIDEO,
|
||||
);
|
||||
|
||||
TUIChatService.sendVideoMessage(options, sendMessageOptions);
|
||||
}
|
||||
|
||||
export function sendFileMessage(
|
||||
currentConversation: IConversationModel,
|
||||
file: any,
|
||||
): void {
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options = createSendMessageOptions(currentConversation, file);
|
||||
const sendMessageOptions = genOfflinePushInfo(
|
||||
currentConversation,
|
||||
options.payload,
|
||||
TUIChatEngine.TYPES.MSG_FILE,
|
||||
);
|
||||
|
||||
TUIChatService.sendFileMessage(options, sendMessageOptions);
|
||||
}
|
||||
|
||||
export function handleWebFileSelect(
|
||||
event: any,
|
||||
sendCallback: (file: any) => void,
|
||||
): void {
|
||||
if (event?.target?.files?.length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendCallback(event.target);
|
||||
event.target.value = '';
|
||||
}
|
||||
|
||||
export function isValidFile(file: any): boolean {
|
||||
return !!file;
|
||||
}
|
||||
|
||||
export function clearFileInput(inputRef: any): void {
|
||||
if (inputRef.value) {
|
||||
inputRef.value.value = '';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user