update
init
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
const directiveList:any = [{
|
||||
name: 'TUILongPress',
|
||||
callback: (el:Element, binding:any, vNode:any) => {
|
||||
// 确保提供的表达式是函数
|
||||
if (typeof binding.value !== 'function') {
|
||||
// 获取组件名称
|
||||
const compName = vNode.context.name;
|
||||
// 将警告传递给控制台
|
||||
let warn = `[longpress:] provided expression '${binding.expression}' is not afunction, but has to be `;
|
||||
if (compName) {
|
||||
warn += `Found in component '${compName}' `;
|
||||
}
|
||||
console.warn(warn);
|
||||
}
|
||||
// 定义变量
|
||||
let pressTimer:any = null;
|
||||
// 定义函数处理程序
|
||||
// 创建计时器( 1秒后执行函数 )
|
||||
const start = (e:any) => {
|
||||
if (e.type === 'click' && e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
if (pressTimer === null) {
|
||||
pressTimer = setTimeout(() => {
|
||||
// 执行函数
|
||||
handler(e);
|
||||
}, 1000);
|
||||
}
|
||||
};
|
||||
// 取消计时器
|
||||
const cancel = (e:any) => {
|
||||
// 检查计时器是否有值
|
||||
if (pressTimer !== null) {
|
||||
clearTimeout(pressTimer);
|
||||
pressTimer = null;
|
||||
}
|
||||
};
|
||||
// 运行函数
|
||||
const handler = (e:any) => {
|
||||
// 执行传递给指令的方法
|
||||
binding.value(e);
|
||||
};
|
||||
// 添加事件监听器
|
||||
el.addEventListener('mousedown', start, false);
|
||||
el.addEventListener('touchstart', start, false);
|
||||
// 取消计时器
|
||||
el.addEventListener('click', cancel);
|
||||
el.addEventListener('mouseout', cancel);
|
||||
el.addEventListener('touchend', cancel);
|
||||
el.addEventListener('touchcancel', cancel);
|
||||
},
|
||||
}];
|
||||
|
||||
const directive = (app: any) => {
|
||||
directiveList.map((item:any) => {
|
||||
app.directive(item.name, {
|
||||
beforeMount: item.callback,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export default directive;
|
||||
@@ -0,0 +1,19 @@
|
||||
const browser = function () {
|
||||
const ua:any = navigator.userAgent,
|
||||
isWindowsPhone = /(?:Windows Phone)/.test(ua),
|
||||
isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,
|
||||
isAndroid = /(?:Android)/.test(ua),
|
||||
isFireFox = /(?:Firefox)/.test(ua),
|
||||
isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)),
|
||||
isPhone = /(?:iPhone)/.test(ua) && !isTablet,
|
||||
isPc = !isPhone && !isAndroid && !isSymbian;
|
||||
return {
|
||||
isTablet: isTablet,
|
||||
isPhone: isPhone,
|
||||
isAndroid: isAndroid,
|
||||
isPC: isPc,
|
||||
isH5: isPhone || isAndroid || isTablet,
|
||||
};
|
||||
};
|
||||
|
||||
export default browser;
|
||||
@@ -0,0 +1,290 @@
|
||||
import { isTypingMessage, JSONToObject } from "../../TUIComponents/container/TUIChat/utils/utils";
|
||||
import TIM from "tim-js-sdk/tim-js-friendship";
|
||||
|
||||
class TUINotification {
|
||||
public allowNotifications = true;
|
||||
public showPreviews = true;
|
||||
public notificationTitle = '腾讯云 IM ';
|
||||
public notificationIcon = 'https://web.sdk.qcloud.com/im/demo/latest/faviconnew.png';
|
||||
|
||||
static TUICore: any;
|
||||
static instance: TUINotification;
|
||||
|
||||
constructor(params?: {
|
||||
allowNotifications?: boolean,
|
||||
showPreviews?: boolean
|
||||
notificationTitle?: string,
|
||||
notificationIcon?: string,
|
||||
}) {
|
||||
if (!params) return;
|
||||
(params?.allowNotifications !== undefined) && (this.allowNotifications = params.allowNotifications);
|
||||
(params?.showPreviews !== undefined) && (this.showPreviews = params.showPreviews);
|
||||
(params?.notificationTitle !== undefined) && (this.notificationTitle = params.notificationTitle);
|
||||
(params?.notificationIcon !== undefined) && (this.notificationIcon = params.notificationIcon);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 TUINotification 实例
|
||||
*
|
||||
* @returns {TUINotification}
|
||||
*/
|
||||
static getInstance(options?: any): TUINotification {
|
||||
if (!TUINotification.instance) {
|
||||
TUINotification.instance = new TUINotification(options);
|
||||
}
|
||||
return TUINotification.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 挂载到 TUICore
|
||||
*
|
||||
* @param {TUICore} TUICore TUICore实例
|
||||
*/
|
||||
static plugin(TUICore: any, options?: any): void {
|
||||
TUICore.config.notification = this.getInstance(options);
|
||||
this.TUICore = TUICore;
|
||||
}
|
||||
|
||||
/**
|
||||
* 挂载到 vue 实例的上
|
||||
*
|
||||
* @param {app} app vue的实例
|
||||
*/
|
||||
static install(app: any): void {
|
||||
app.use(this.getInstance());
|
||||
}
|
||||
|
||||
public setNotificationConfiguration(params?: {
|
||||
allowNotifications?: boolean,
|
||||
showPreviews?: boolean
|
||||
notificationTitle?: string,
|
||||
notificationIcon?: string,
|
||||
}): void {
|
||||
if (!params) return;
|
||||
(params?.allowNotifications !== undefined) && (this.allowNotifications = params.allowNotifications);
|
||||
(params?.showPreviews !== undefined) && (this.showPreviews = params.showPreviews);
|
||||
(params?.notificationTitle !== undefined) && (this.notificationTitle = params.notificationTitle);
|
||||
(params?.notificationIcon !== undefined) && (this.notificationIcon = params.notificationIcon);
|
||||
}
|
||||
|
||||
public async notify(message: any): Promise<void> {
|
||||
if (!this.allowNotifications) {
|
||||
return;
|
||||
}
|
||||
if (!this.checkNotificationAbility()) {
|
||||
return;
|
||||
}
|
||||
if (!await this.requestNotificationPermission()) {
|
||||
return;
|
||||
}
|
||||
await this.handleNotification(message);
|
||||
}
|
||||
|
||||
public checkNotificationAbility(): boolean {
|
||||
if (!('Notification' in window) || window.Notification.permission === 'denied') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public requestNotificationPermission(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!window?.Notification) reject(false);
|
||||
if (window.Notification.permission === 'granted') {
|
||||
resolve(true);
|
||||
}
|
||||
window.Notification.requestPermission().then(permission => {
|
||||
// 如果用户同意,就可以向他们发送通知
|
||||
if (permission === 'granted') {
|
||||
resolve(true);
|
||||
}
|
||||
}).catch(() => {
|
||||
reject(false);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async handleNotification(message: any): Promise<void> {
|
||||
if (!this._isMessageNeedNotification(message)) return;
|
||||
const notificationType = this._handleNotificationType(message);
|
||||
let content;
|
||||
let options = {
|
||||
badge: this.notificationIcon,
|
||||
icon: this.notificationIcon,
|
||||
body: '',
|
||||
requireInteraction: false,
|
||||
}
|
||||
|
||||
switch (notificationType) {
|
||||
case 'call':
|
||||
content = this._handleCallNotificationContent(message);
|
||||
if (!content?.content) {
|
||||
return;
|
||||
}
|
||||
options.body = content.content;
|
||||
options.requireInteraction = !content.callEnd;
|
||||
break;
|
||||
case 'chat':
|
||||
options.body = await this._handleChatNotificationContent(message);
|
||||
options.requireInteraction = false;
|
||||
break;
|
||||
}
|
||||
|
||||
const notification = new Notification(this.notificationTitle, options);
|
||||
|
||||
notification.onclick = () => {
|
||||
window.focus();
|
||||
if (!message || !message?.conversationID) {
|
||||
return;
|
||||
}
|
||||
const TUIConversationServer = TUINotification?.TUICore?.TUIServer?.TUIConversation;
|
||||
if (message?.conversationType === TIM.TYPES.CONV_C2C || message?.conversationType === TIM.TYPES.CONV_GROUP) {
|
||||
TUIConversationServer?.getConversationProfile(message?.conversationID).then((imResponse: any) => {
|
||||
imResponse?.data?.conversation && TUIConversationServer.handleCurrentConversation(imResponse?.data?.conversation);
|
||||
})
|
||||
}
|
||||
notification.close()
|
||||
}
|
||||
}
|
||||
|
||||
private _isMessageNeedNotification(message: any): boolean {
|
||||
if (!message || !message?.ID || !message?.type ||
|
||||
message?.isRevoked || message?.isDeleted ||
|
||||
(isTypingMessage && isTypingMessage(message))) {
|
||||
return false;
|
||||
}
|
||||
if (message?.type === TIM.TYPES.MSG_GRP_TIP || message?.type === TIM.TYPES.MSG_GRP_SYS_NOTICE) {
|
||||
return false;
|
||||
}
|
||||
const currentConversationID = TUINotification?.TUICore?.TUIServer?.TUIConversation?.currentStore?.currentConversationID;
|
||||
if (this.checkPageFocus() && message?.conversationID === currentConversationID) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private _handleNotificationType(message: any): string {
|
||||
if (message.type === TIM.TYPES.MSG_CUSTOM) {
|
||||
const payloadData = JSONToObject(message?.payload?.data);
|
||||
if (payloadData?.businessID === 1 || payloadData?.businessID === 'av_call') {
|
||||
return 'call';
|
||||
}
|
||||
}
|
||||
return 'chat';
|
||||
}
|
||||
|
||||
private async _handleChatNotificationContent(message: any): Promise<string> {
|
||||
let content = '';
|
||||
if (!message || !message?.ID || !message?.type) {
|
||||
return content
|
||||
}
|
||||
switch (this.showPreviews) {
|
||||
case true:
|
||||
content = await this._handleChatNotificationContentTitle(message);
|
||||
content += this._handleChatNotificationContentText(message);
|
||||
break;
|
||||
case false:
|
||||
content = '您有' + await TUINotification?.TUICore?.tim?.getTotalUnreadMessageCount() + '条新消息';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
private async _handleChatNotificationContentTitle(message: any): Promise<string> {
|
||||
let title = '';
|
||||
switch (message?.conversationType) {
|
||||
case TIM.TYPES.CONV_C2C:
|
||||
title = (message?.nick || message?.from) + ': ';
|
||||
break;
|
||||
case TIM.TYPES.CONV_GROUP:
|
||||
title = message?.conversationID + ': ';
|
||||
await TUINotification?.TUICore?.tim?.getConversationProfile(message?.conversationID)?.then((imResponse: any) => {
|
||||
title = (imResponse?.data?.conversation?.groupProfile?.name || message?.conversationID) + ': ';
|
||||
}).catch(() => {
|
||||
title = message?.conversationID + ': ';
|
||||
})
|
||||
break;
|
||||
case TIM.TYPES.CONV_SYSTEM:
|
||||
title = '系统消息: ';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
||||
private _handleChatNotificationContentText(message: any): string {
|
||||
let content = '';
|
||||
switch (message.type) {
|
||||
case TIM.TYPES.MSG_TEXT:
|
||||
content += message?.payload?.text;
|
||||
break;
|
||||
case TIM.TYPES.MSG_CUSTOM:
|
||||
content += '[自定义消息]';
|
||||
break;
|
||||
case TIM.TYPES.MSG_IMAGE:
|
||||
content += '[图片]';
|
||||
break;
|
||||
case TIM.TYPES.MSG_AUDIO:
|
||||
content += '[语音]';
|
||||
break;
|
||||
case TIM.TYPES.MSG_VIDEO:
|
||||
content += '[视频]';
|
||||
break;
|
||||
case TIM.TYPES.MSG_FILE:
|
||||
content += '[文件]';
|
||||
break;
|
||||
case TIM.TYPES.MSG_FACE:
|
||||
content += '[表情]';
|
||||
break;
|
||||
case TIM.TYPES.MSG_MERGER:
|
||||
content += '[聊天记录]';
|
||||
break;
|
||||
case TIM.TYPES.MSG_LOCATION:
|
||||
content += '[位置]';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
private _handleCallNotificationContent(message: any): { content: string, callEnd: boolean } {
|
||||
let content = '';
|
||||
let callEnd = false;
|
||||
try {
|
||||
if (message.type === TIM.TYPES.MSG_CUSTOM) {
|
||||
const callInfo = JSONToObject(message?.payload?.data);
|
||||
const callDataInfo = JSONToObject(callInfo.data);
|
||||
if (callInfo?.businessID === 1) {
|
||||
if (callInfo.actionType === 1 && (
|
||||
(callInfo.groupID && callInfo.timeout > 0) ||
|
||||
((!callInfo.call_end && callInfo.call_end !== 0) &&
|
||||
!callInfo.groupID &&
|
||||
!(callDataInfo?.data && (callDataInfo?.data.cmd === 'switchToAudio' || callDataInfo?.data.cmd === 'switchToVideo')))
|
||||
)) {
|
||||
content = this.showPreviews ? `${callInfo.inviter} 发起通话` : `您有一个通话请求`;
|
||||
callEnd = false;
|
||||
} else if (callInfo.actionType === 2) {
|
||||
content = this.showPreviews ? `${callInfo.inviter} 取消通话` : `通话取消`;
|
||||
callEnd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.warn(error);
|
||||
}
|
||||
return {
|
||||
content,
|
||||
callEnd
|
||||
}
|
||||
}
|
||||
|
||||
public checkPageFocus(): boolean {
|
||||
return document.hasFocus();
|
||||
}
|
||||
}
|
||||
|
||||
export default TUINotification;
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
|
||||
const data = {
|
||||
theme: 'dark',
|
||||
};
|
||||
|
||||
function plugin(TUICore:any) {
|
||||
TUICore.setCommonStore(data);
|
||||
}
|
||||
|
||||
function install(app:any) {
|
||||
console.log('app', app);
|
||||
}
|
||||
|
||||
const TUIColor = {
|
||||
name: 'TUITheme',
|
||||
plugin,
|
||||
install,
|
||||
};
|
||||
|
||||
export default TUIColor;
|
||||
@@ -0,0 +1,88 @@
|
||||
import { createI18n, useI18n } from 'vue-i18n';
|
||||
import messages from '../../locales';
|
||||
|
||||
class TUIi18n {
|
||||
public messages = {
|
||||
en: {},
|
||||
zh_cn: {},
|
||||
};
|
||||
public i18n: any;
|
||||
static instance: TUIi18n;
|
||||
constructor(messages:any) {
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 TUIi18n 实例
|
||||
*
|
||||
* @returns {TUIi18n}
|
||||
*/
|
||||
static getInstance() {
|
||||
if (!TUIi18n.instance) {
|
||||
TUIi18n.instance = new TUIi18n(messages);
|
||||
}
|
||||
return TUIi18n.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入需要国际化的词条
|
||||
*
|
||||
* @param {Object} messages 数据对象
|
||||
* @returns {messages} 全部国际化词条
|
||||
*/
|
||||
public provideMessage(messages: any) {
|
||||
this.messages.en = { ...this.messages.en, ...messages.en };
|
||||
this.messages.zh_cn = { ...this.messages.zh_cn, ...messages.zh_cn };
|
||||
return this.messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用国际化
|
||||
*
|
||||
* @returns {useI18n} 国际化使用函数
|
||||
*/
|
||||
public useI18n() {
|
||||
return useI18n();
|
||||
}
|
||||
|
||||
/**
|
||||
* 挂载到 vue 实例的上
|
||||
*
|
||||
* @param {app} app vue的实例
|
||||
*/
|
||||
static install(app: any) {
|
||||
const that = TUIi18n.getInstance();
|
||||
// const lang = navigator.language.substr(0, 2);
|
||||
const lang = 'zh';
|
||||
that.i18n = createI18n({
|
||||
legacy: false, // 使用Composition API,这里必须设置为false
|
||||
globalInjection: true,
|
||||
global: true,
|
||||
locale: lang === 'zh' ? 'zh_cn' : lang,
|
||||
fallbackLocale: 'zh_cn', // 默认语言
|
||||
messages: that.messages,
|
||||
});
|
||||
app.use(that.i18n);
|
||||
}
|
||||
|
||||
/**
|
||||
* 挂载到 TUICore
|
||||
*
|
||||
* @param {TUICore} TUICore TUICore实例
|
||||
*/
|
||||
static plugin(TUICore:any) {
|
||||
TUICore.config.i18n = TUIi18n.getInstance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 国际化标识
|
||||
*
|
||||
* @returns {locale} 国际化标识
|
||||
*/
|
||||
export function useI18nLocale() {
|
||||
return TUIi18n.getInstance().i18n.global.locale;
|
||||
}
|
||||
|
||||
export default TUIi18n;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import TUITheme from './TUITheme';
|
||||
import TUIi18n from './TUIi18n';
|
||||
import TUIEnv from './TUIEnv';
|
||||
import TUIDirective from './TUIDirective';
|
||||
import TUINotification from './TUINotification';
|
||||
|
||||
export { TUITheme, TUIi18n, TUIEnv, TUIDirective, TUINotification };
|
||||
Reference in New Issue
Block a user