消息
This commit is contained in:
23
TUIKit/utils/documentLink.ts
Normal file
23
TUIKit/utils/documentLink.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
const Link = {
|
||||
product: {
|
||||
label: '产品文档',
|
||||
url: 'https://cloud.tencent.com/document/product/269/1499#.E7.BE.A4.E7.BB.84.E5.8A.9F.E8.83.BD',
|
||||
},
|
||||
customMessage: {
|
||||
label: '自定义消息',
|
||||
url: 'https://web.sdk.qcloud.com/im/doc/v3/zh-cn/SDK.html#createCustomMessage',
|
||||
},
|
||||
complaint: {
|
||||
label: '点此投诉',
|
||||
url: 'https://cloud.tencent.com/apply/p/xc3oaubi98g',
|
||||
},
|
||||
implement: {
|
||||
label: '集成TUICallKit',
|
||||
url: 'https://cloud.tencent.com/document/product/269/79861',
|
||||
},
|
||||
purchase: {
|
||||
label: '开通腾讯实时音视频服务',
|
||||
url: 'https://cloud.tencent.com/document/product/1640/79968',
|
||||
},
|
||||
};
|
||||
export default Link;
|
||||
8
TUIKit/utils/enableSampleTaskStatus.ts
Normal file
8
TUIKit/utils/enableSampleTaskStatus.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { TUIStore, StoreName } from "@tencentcloud/chat-uikit-engine";
|
||||
export function enableSampleTaskStatus(taskKey: string) {
|
||||
const tasks = TUIStore.getData(StoreName.APP, "tasks");
|
||||
if (taskKey in tasks && !tasks[taskKey]) {
|
||||
tasks[taskKey] = true;
|
||||
TUIStore.update(StoreName.APP, "tasks", tasks);
|
||||
}
|
||||
}
|
||||
17
TUIKit/utils/env.ts
Normal file
17
TUIKit/utils/env.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { getPlatform } from '@tencentcloud/universal-api';
|
||||
|
||||
declare const uni: any;
|
||||
|
||||
export const isPC = getPlatform() === 'pc';
|
||||
|
||||
export const isH5 = getPlatform() === 'h5';
|
||||
|
||||
export const isWeChat = getPlatform() === 'wechat';
|
||||
|
||||
export const isApp = getPlatform() === 'app';
|
||||
|
||||
export const isUniFrameWork = typeof uni !== 'undefined';
|
||||
|
||||
// H5, mini programs, and apps are all considered mobile.
|
||||
// If you need to unify the mobile UI style, you can directly use isMobile to control
|
||||
export const isMobile = isH5 || isWeChat || isApp;
|
||||
1
TUIKit/utils/index.ts
Normal file
1
TUIKit/utils/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./type-check";
|
||||
169
TUIKit/utils/lodash.ts
Normal file
169
TUIKit/utils/lodash.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck
|
||||
/** Error message constants. */
|
||||
const FUNC_ERROR_TEXT = 'Expected a function';
|
||||
|
||||
interface IDebounceOptions {
|
||||
leading?: boolean;
|
||||
maxWait?: number;
|
||||
trailing?: boolean;
|
||||
}
|
||||
|
||||
type IThrottleOptions = IDebounceOptions;
|
||||
|
||||
function throttle(func, wait: number, options?: IThrottleOptions) {
|
||||
let leading = true,
|
||||
trailing = true;
|
||||
|
||||
if (typeof func != 'function') {
|
||||
throw new TypeError(FUNC_ERROR_TEXT);
|
||||
}
|
||||
if (options && isObject(options)) {
|
||||
leading = 'leading' in options ? !!options.leading : leading;
|
||||
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
||||
}
|
||||
return debounce(func, wait, {
|
||||
leading: leading,
|
||||
maxWait: wait,
|
||||
trailing: trailing,
|
||||
});
|
||||
}
|
||||
|
||||
function debounce(func, wait: number, options?: IDebounceOptions) {
|
||||
let lastArgs,
|
||||
lastThis,
|
||||
maxWait,
|
||||
result,
|
||||
timerId,
|
||||
lastCallTime,
|
||||
lastInvokeTime = 0,
|
||||
leading = false,
|
||||
maxing = false,
|
||||
trailing = true;
|
||||
|
||||
if (typeof func != 'function') {
|
||||
throw new TypeError(FUNC_ERROR_TEXT);
|
||||
}
|
||||
wait = wait || 0;
|
||||
if (options && isObject(options)) {
|
||||
leading = !!options.leading;
|
||||
maxing = 'maxWait' in options;
|
||||
maxWait = maxing ? Math.max(options.maxWait || 0, wait) : maxWait;
|
||||
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
||||
}
|
||||
|
||||
function invokeFunc(time) {
|
||||
const args = lastArgs,
|
||||
thisArg = lastThis;
|
||||
|
||||
lastArgs = lastThis = undefined;
|
||||
lastInvokeTime = time;
|
||||
result = func.apply(thisArg, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
function leadingEdge(time) {
|
||||
// Reset any `maxWait` timer.
|
||||
lastInvokeTime = time;
|
||||
// Start the timer for the trailing edge.
|
||||
timerId = setTimeout(timerExpired, wait);
|
||||
// Invoke the leading edge.
|
||||
return leading ? invokeFunc(time) : result;
|
||||
}
|
||||
|
||||
function remainingWait(time) {
|
||||
const timeSinceLastCall = time - lastCallTime,
|
||||
timeSinceLastInvoke = time - lastInvokeTime,
|
||||
timeWaiting = wait - timeSinceLastCall;
|
||||
|
||||
return maxing
|
||||
? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)
|
||||
: timeWaiting;
|
||||
}
|
||||
|
||||
function shouldInvoke(time) {
|
||||
const timeSinceLastCall = time - lastCallTime,
|
||||
timeSinceLastInvoke = time - lastInvokeTime;
|
||||
|
||||
// Either this is the first call, activity has stopped and we're at the
|
||||
// trailing edge, the system time has gone backwards and we're treating
|
||||
// it as the trailing edge, or we've hit the `maxWait` limit.
|
||||
return (lastCallTime === undefined || (timeSinceLastCall >= wait)
|
||||
|| (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
|
||||
}
|
||||
|
||||
function timerExpired() {
|
||||
const time = Date.now();
|
||||
if (shouldInvoke(time)) {
|
||||
return trailingEdge(time);
|
||||
}
|
||||
// Restart the timer.
|
||||
timerId = setTimeout(timerExpired, remainingWait(time));
|
||||
}
|
||||
|
||||
function trailingEdge(time) {
|
||||
timerId = undefined;
|
||||
|
||||
// Only invoke if we have `lastArgs` which means `func` has been
|
||||
// debounced at least once.
|
||||
if (trailing && lastArgs) {
|
||||
return invokeFunc(time);
|
||||
}
|
||||
lastArgs = lastThis = undefined;
|
||||
return result;
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
if (timerId !== undefined) {
|
||||
clearTimeout(timerId);
|
||||
}
|
||||
lastInvokeTime = 0;
|
||||
lastArgs = lastCallTime = lastThis = timerId = undefined;
|
||||
}
|
||||
|
||||
function flush() {
|
||||
return timerId === undefined ? result : trailingEdge(Date.now());
|
||||
}
|
||||
|
||||
function debounced() {
|
||||
const time = Date.now(),
|
||||
isInvoking = shouldInvoke(time);
|
||||
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
lastArgs = arguments;
|
||||
|
||||
// @ts-expect-error ignore this type
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
lastThis = this;
|
||||
lastCallTime = time;
|
||||
|
||||
if (isInvoking) {
|
||||
if (timerId === undefined) {
|
||||
return leadingEdge(lastCallTime);
|
||||
}
|
||||
if (maxing) {
|
||||
// Handle invocations in a tight loop.
|
||||
clearTimeout(timerId);
|
||||
timerId = setTimeout(timerExpired, wait);
|
||||
return invokeFunc(lastCallTime);
|
||||
}
|
||||
}
|
||||
if (timerId === undefined) {
|
||||
timerId = setTimeout(timerExpired, wait);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
debounced.cancel = cancel;
|
||||
debounced.flush = flush;
|
||||
return debounced;
|
||||
}
|
||||
|
||||
function isObject(value) {
|
||||
const type = typeof value;
|
||||
return value != null && (type == 'object' || type == 'function');
|
||||
}
|
||||
|
||||
export {
|
||||
debounce,
|
||||
throttle,
|
||||
};
|
||||
53
TUIKit/utils/riseInput.ts
Normal file
53
TUIKit/utils/riseInput.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { isIOS } from '@tencentcloud/universal-api';
|
||||
const ua = navigator.userAgent;
|
||||
|
||||
function getScrollTypeByPlatform() {
|
||||
if (isIOS) {
|
||||
if (/Safari\//.test(ua) || /IOS 11_[0-3]\D/.test(ua)) {
|
||||
// Safari IOS 11.0-11.3 exclude(`scrollTop`/`scrolIntoView` not working)
|
||||
return 0;
|
||||
}
|
||||
// IOS: use `scrollTop`
|
||||
return 1;
|
||||
}
|
||||
// Android: use `scrollIntoView`
|
||||
return 2;
|
||||
}
|
||||
|
||||
export default function riseInput(input: HTMLElement, target?: HTMLElement) {
|
||||
const scrollType = getScrollTypeByPlatform();
|
||||
let scrollTimer: ReturnType<typeof setTimeout>;
|
||||
|
||||
if (!target) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
target = input;
|
||||
}
|
||||
|
||||
const scrollIntoView = () => {
|
||||
if (scrollType === 0) return;
|
||||
if (scrollType === 1) {
|
||||
document.body.scrollTop = document.body.scrollHeight;
|
||||
} else {
|
||||
target?.scrollIntoView(false);
|
||||
}
|
||||
};
|
||||
|
||||
input.addEventListener('focus', () => {
|
||||
const timer = setTimeout(() => {
|
||||
scrollIntoView();
|
||||
clearTimeout(timer);
|
||||
}, 300);
|
||||
scrollTimer = setTimeout(scrollIntoView, 1000);
|
||||
});
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
clearTimeout(scrollTimer);
|
||||
// Handle IOS issues about keyboard is hidden but page not refreshed
|
||||
if (scrollType && isIOS) {
|
||||
const timer = setTimeout(() => {
|
||||
document.body.scrollIntoView();
|
||||
clearTimeout(timer);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
44
TUIKit/utils/type-check.ts
Normal file
44
TUIKit/utils/type-check.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
const objectToString = Object.prototype.toString;
|
||||
const toTypeString = (value: any) => objectToString.call(value);
|
||||
|
||||
export const { isArray } = Array;
|
||||
export const isMap = (val: any) => toTypeString(val) === '[object Map]';
|
||||
export const isSet = (val: any) => toTypeString(val) === '[object Set]';
|
||||
export const isDate = (val: any) => val instanceof Date;
|
||||
export const isFunction = (val: any) => typeof val === 'function';
|
||||
export const isString = (val: any) => typeof val === 'string';
|
||||
export const isSymbol = (val: any) => typeof val === 'symbol';
|
||||
export const isObject = (val: any) => val !== null && typeof val === 'object';
|
||||
export const isPromise = (val: any) =>
|
||||
isObject(val) && isFunction(val.then) && isFunction(val.catch);
|
||||
// Determine whether it is url
|
||||
export const isUrl = (url: string) => {
|
||||
return /^(https?:\/\/(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+)(:\d+)?(\/.*)?(\?.*)?(#.*)?$/.test(
|
||||
url,
|
||||
);
|
||||
};
|
||||
|
||||
// Determine if it is a JSON string
|
||||
export const isJSON = (str: string) => {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
if (typeof str === 'string') {
|
||||
try {
|
||||
const data = JSON.parse(str);
|
||||
if (data) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (error: any) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Determine if it is a JSON string
|
||||
export const JSONToObject = (str: string) => {
|
||||
if (!str || !isJSON(str)) {
|
||||
return str;
|
||||
}
|
||||
return JSON.parse(str);
|
||||
};
|
||||
27
TUIKit/utils/unifyPromiseVue2.ts
Normal file
27
TUIKit/utils/unifyPromiseVue2.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
export default function unifyPromiseVue2() {
|
||||
try {
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
function isPromise(obj) {
|
||||
return Boolean(obj) && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
|
||||
}
|
||||
// Unified vue2 API Promise return format to be consistent with vue3
|
||||
// eslint-disable-next-line no-undef
|
||||
(uni as any).addInterceptor({
|
||||
returnValue(res) {
|
||||
if (!isPromise(res)) {
|
||||
return res;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
res.then((res) => {
|
||||
if (res[0]) {
|
||||
reject(res[0]);
|
||||
} else {
|
||||
resolve(res[1]);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (error) { }
|
||||
}
|
||||
Reference in New Issue
Block a user