新增功能
@@ -0,0 +1,63 @@
|
||||
<p align="center">
|
||||
<a href="https://trtc.io/">
|
||||
<img width="200" src="https://web.sdk.qcloud.com/trtc/webrtc/assets/trtc.io-logo.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h1 align="center" style="margin-top: -40px">TUICallEngine WX SDK</h1>
|
||||
|
||||
<div align="center">
|
||||
|
||||
 [](https://www.npmjs.com/package/@trtc/call-engine-lite-wx) [](https://www.npmjs.com/package/@trtc/call-engine-lite-wx) [](https://cloud.tencent.com/document/product/647/78761) [](https://github.com/tencentyun/TUICallKit)
|
||||
|
||||
</div>
|
||||
|
||||
<div align="center"> English | <a href="https://github.com/tencentyun/TUICallKit/tree/main/Web/call-engine-demo-vue3" target="_blank"> 简体中文</a> </div>
|
||||
|
||||
|
||||
## 简介
|
||||
TUICallEngine 是基于腾讯云 [即时通信 IM](https://cloud.tencent.com/document/product/269/42440) 和 [实时音视频 TRTC](https://cloud.tencent.com/document/product/647/16788) 两项付费 PaaS 服务构建出的音视频通信 SDK,支持双人和多人场景下的音视频通话。
|
||||
|
||||
- 我们提供适用于 Web、Android、iOS、小程序、Flutter 的 SDK,更多信息请参见 [trtc.io](https://cloud.tencent.com/document/product/647/78742)。
|
||||
|
||||
|
||||
## 安装
|
||||
使用 npm:
|
||||
```
|
||||
$ npm install @trtc/call-engine-lite-wx --save
|
||||
```
|
||||
|
||||
使用 yarn:
|
||||
```
|
||||
$ yarn add @trtc/call-engine-lite-wx
|
||||
```
|
||||
|
||||
手动下载 sdk 包:
|
||||
1. 下载 [@trtc/call-engine-lite-wx](https://www.unpkg.com/@trtc/call-engine-lite-wx@latest)。
|
||||
2. 将 `@trtc/call-engine-lite-wx` 复制到你的项目中。
|
||||
|
||||
|
||||
## API 概要
|
||||
- [tuiCallEngine](https://cloud.tencent.com/document/product/647/78761#createinstance) 对象,提供实时音视频通话的核心能力。
|
||||
- 开始 1v1(或多人) 通话 [calls](https://cloud.tencent.com/document/product/647/78761#calls)
|
||||
- 接通 [accept](https://cloud.tencent.com/document/product/647/78761#accept)
|
||||
- 拒绝 [reject](https://cloud.tencent.com/document/product/647/78761#reject)
|
||||
- 挂断 [hangup](https://cloud.tencent.com/document/product/647/78761#hangup)
|
||||
- 打开摄像头 [openCamera](https://cloud.tencent.com/document/product/647/78761#opencamera)
|
||||
- 打开麦克风 [openMicrophone](https://cloud.tencent.com/document/product/647/78761#openmicrophone)
|
||||
- 关闭摄像头 [closeCamera](https://cloud.tencent.com/document/product/647/78761#closecamera)
|
||||
- 关闭麦克风 [closeMicrophone](https://cloud.tencent.com/document/product/647/78761#closemicrophone)
|
||||
- 播放远端视频 [startRemoteView](https://cloud.tencent.com/document/product/647/78761#startremoteView)
|
||||
- 停止播放远端视频 [stopRemoteView](https://cloud.tencent.com/document/product/647/78761#stopremoteView)
|
||||
|
||||
|
||||
## 目录结构
|
||||
```
|
||||
├── README-zh_CN.md
|
||||
├── README.md
|
||||
├── index.js // 基于 umd 模块的 sdk 包
|
||||
├── index.esm.js // 基于 esm 模块的 sdk 包
|
||||
├── index.cjs.js // 基于 commonjs 模块的 sdk 包
|
||||
├── index.d.ts // 类型声明文件
|
||||
└── package.json
|
||||
```
|
||||
@@ -0,0 +1,70 @@
|
||||
<p align="center">
|
||||
<a href="https://trtc.io/">
|
||||
<img width="200" src="https://web.sdk.qcloud.com/trtc/webrtc/assets/trtc.io-logo.png">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h1 align="center" style="margin-top: -40px">TUICallEngine WX SDK</h1>
|
||||
|
||||
<div align="center">
|
||||
|
||||
An object-oriented TUICallEngine SDK library
|
||||
|
||||
 [](https://www.npmjs.com/package/@trtc/call-engine-lite-wx) [](https://www.npmjs.com/package/@trtc/call-engine-lite-wx) [](https://cloud.tencent.com/document/product/647/78761) [](https://github.com/tencentyun/TUICallKit)
|
||||
|
||||
</div>
|
||||
|
||||
<div align="center"> English | <a href="https://github.com/Tencent-RTC/rtc-call-engine/tree/main/Web/demo-vue3" target="_blank"> 简体中文</a> </div>
|
||||
|
||||
|
||||
## Install
|
||||
npm:
|
||||
```
|
||||
$ npm install @trtc/call-engine-lite-wx --save
|
||||
```
|
||||
|
||||
yarn:
|
||||
```
|
||||
$ yarn add @trtc/call-engine-lite-wx
|
||||
```
|
||||
|
||||
Download manually:
|
||||
|
||||
1. download [@trtc/call-engine-lite-wx](https://www.unpkg.com/@trtc/call-engine-lite-wx@latest).
|
||||
2. copy `@trtc/call-engine-lite-wx` to your project.
|
||||
|
||||
|
||||
## Usage
|
||||
Refer to the following two tutorials for a quick run-through of the demo and how to use the SDK to implement basic audio and video calling functionality.
|
||||
|
||||
- [Demo Quick Run](https://web.sdk.qcloud.com/component/trtccalling/doc/TUICallEngine/web/en/tutorial-00-%E5%AE%9E%E7%8E%B0%E5%8F%8C%E4%BA%BA%E9%80%9A%E8%AF%9D.html)
|
||||
- [TUICallEngine Github Demo](https://github.com/Tencent-RTC/rtc-call-engine/tree/main/Web/demo-vue3)
|
||||
|
||||
Explore SDK documents:[TUICallEngine WX SDK](https://cloud.tencent.com/document/product/647/78761)
|
||||
|
||||
|
||||
## API Overview
|
||||
- [tuiCallEngine](https://cloud.tencent.com/document/product/647/78761#createinstance) instance, provides the core capability for real-time audio and video calls.
|
||||
- Start single or group calls [calls](https://cloud.tencent.com/document/product/647/78761#calls)
|
||||
- Accept call [accept](https://cloud.tencent.com/document/product/647/78761#accept)
|
||||
- Reject call [reject](https://cloud.tencent.com/document/product/647/78761#reject)
|
||||
- Hangup call [hangup](https://cloud.tencent.com/document/product/647/78761#hangup)
|
||||
- Turn on camera [openCamera](https://cloud.tencent.com/document/product/647/78761#opencamera)
|
||||
- Turn on microphone [openMicrophone](https://cloud.tencent.com/document/product/647/78761#openmicrophone)
|
||||
- Turn off camera [closeCamera](https://cloud.tencent.com/document/product/647/78761#closecamera)
|
||||
- Turn off microphone [closeMicrophone](https://cloud.tencent.com/document/product/647/78761#closemicrophone)
|
||||
- Play remote video [startRemoteView](https://cloud.tencent.com/document/product/647/78761#startremoteView)
|
||||
- Stop playing remote video [stopRemoteView](https://cloud.tencent.com/document/product/647/78761#stopremoteView)
|
||||
|
||||
|
||||
## Directory
|
||||
```
|
||||
├── README-zh_CN.md
|
||||
├── README.md
|
||||
├── index.js // sdk file base on UMD modules
|
||||
├── index.esm.js // sdk file base on ESM modules
|
||||
├── index.cjs.js // sdk file base on CommonJS modules
|
||||
├── index.d.ts // ts declaration file
|
||||
└── package.json
|
||||
```
|
||||
`
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Arnout Kazemier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,94 @@
|
||||
# EventEmitter3
|
||||
|
||||
[](https://www.npmjs.com/package/eventemitter3)[](https://travis-ci.org/primus/eventemitter3)[](https://david-dm.org/primus/eventemitter3)[](https://coveralls.io/r/primus/eventemitter3?branch=master)[](https://webchat.freenode.net/?channels=primus)
|
||||
|
||||
[](https://saucelabs.com/u/eventemitter3)
|
||||
|
||||
EventEmitter3 is a high performance EventEmitter. It has been micro-optimized
|
||||
for various of code paths making this, one of, if not the fastest EventEmitter
|
||||
available for Node.js and browsers. The module is API compatible with the
|
||||
EventEmitter that ships by default with Node.js but there are some slight
|
||||
differences:
|
||||
|
||||
- Domain support has been removed.
|
||||
- We do not `throw` an error when you emit an `error` event and nobody is
|
||||
listening.
|
||||
- The `newListener` and `removeListener` events have been removed as they
|
||||
are useful only in some uncommon use-cases.
|
||||
- The `setMaxListeners`, `getMaxListeners`, `prependListener` and
|
||||
`prependOnceListener` methods are not available.
|
||||
- Support for custom context for events so there is no need to use `fn.bind`.
|
||||
- The `removeListener` method removes all matching listeners, not only the
|
||||
first.
|
||||
|
||||
It's a drop in replacement for existing EventEmitters, but just faster. Free
|
||||
performance, who wouldn't want that? The EventEmitter is written in EcmaScript 3
|
||||
so it will work in the oldest browsers and node versions that you need to
|
||||
support.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
$ npm install --save eventemitter3
|
||||
```
|
||||
|
||||
## CDN
|
||||
|
||||
Recommended CDN:
|
||||
|
||||
```text
|
||||
https://unpkg.com/eventemitter3@latest/umd/eventemitter3.min.js
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
After installation the only thing you need to do is require the module:
|
||||
|
||||
```js
|
||||
var EventEmitter = require('eventemitter3');
|
||||
```
|
||||
|
||||
And you're ready to create your own EventEmitter instances. For the API
|
||||
documentation, please follow the official Node.js documentation:
|
||||
|
||||
http://nodejs.org/api/events.html
|
||||
|
||||
### Contextual emits
|
||||
|
||||
We've upgraded the API of the `EventEmitter.on`, `EventEmitter.once` and
|
||||
`EventEmitter.removeListener` to accept an extra argument which is the `context`
|
||||
or `this` value that should be set for the emitted events. This means you no
|
||||
longer have the overhead of an event that required `fn.bind` in order to get a
|
||||
custom `this` value.
|
||||
|
||||
```js
|
||||
var EE = new EventEmitter()
|
||||
, context = { foo: 'bar' };
|
||||
|
||||
function emitted() {
|
||||
console.log(this === context); // true
|
||||
}
|
||||
|
||||
EE.once('event-name', emitted, context);
|
||||
EE.on('another-event', emitted, context);
|
||||
EE.removeListener('another-event', emitted, context);
|
||||
```
|
||||
|
||||
### Tests and benchmarks
|
||||
|
||||
This module is well tested. You can run:
|
||||
|
||||
- `npm test` to run the tests under Node.js.
|
||||
- `npm run test-browser` to run the tests in real browsers via Sauce Labs.
|
||||
|
||||
We also have a set of benchmarks to compare EventEmitter3 with some available
|
||||
alternatives. To run the benchmarks run `npm run benchmark`.
|
||||
|
||||
Tests and benchmarks are not included in the npm package. If you want to play
|
||||
with them you have to clone the GitHub repository.
|
||||
Note that you will have to run an additional `npm i` in the benchmarks folder
|
||||
before `npm run benchmark`.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Minimal `EventEmitter` interface that is molded against the Node.js
|
||||
* `EventEmitter` interface.
|
||||
*/
|
||||
declare class EventEmitter<
|
||||
EventTypes extends EventEmitter.ValidEventTypes = string | symbol,
|
||||
Context extends any = any
|
||||
> {
|
||||
static prefixed: string | boolean;
|
||||
|
||||
/**
|
||||
* Return an array listing the events for which the emitter has registered
|
||||
* listeners.
|
||||
*/
|
||||
eventNames(): Array<EventEmitter.EventNames<EventTypes>>;
|
||||
|
||||
/**
|
||||
* Return the listeners registered for a given event.
|
||||
*/
|
||||
listeners<T extends EventEmitter.EventNames<EventTypes>>(
|
||||
event: T
|
||||
): Array<EventEmitter.EventListener<EventTypes, T>>;
|
||||
|
||||
/**
|
||||
* Return the number of listeners listening to a given event.
|
||||
*/
|
||||
listenerCount(event: EventEmitter.EventNames<EventTypes>): number;
|
||||
|
||||
/**
|
||||
* Calls each of the listeners registered for a given event.
|
||||
*/
|
||||
emit<T extends EventEmitter.EventNames<EventTypes>>(
|
||||
event: T,
|
||||
...args: EventEmitter.EventArgs<EventTypes, T>
|
||||
): boolean;
|
||||
|
||||
/**
|
||||
* Add a listener for a given event.
|
||||
*/
|
||||
on<T extends EventEmitter.EventNames<EventTypes>>(
|
||||
event: T,
|
||||
fn: EventEmitter.EventListener<EventTypes, T>,
|
||||
context?: Context
|
||||
): this;
|
||||
addListener<T extends EventEmitter.EventNames<EventTypes>>(
|
||||
event: T,
|
||||
fn: EventEmitter.EventListener<EventTypes, T>,
|
||||
context?: Context
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Add a one-time listener for a given event.
|
||||
*/
|
||||
once<T extends EventEmitter.EventNames<EventTypes>>(
|
||||
event: T,
|
||||
fn: EventEmitter.EventListener<EventTypes, T>,
|
||||
context?: Context
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Remove the listeners of a given event.
|
||||
*/
|
||||
removeListener<T extends EventEmitter.EventNames<EventTypes>>(
|
||||
event: T,
|
||||
fn?: EventEmitter.EventListener<EventTypes, T>,
|
||||
context?: Context,
|
||||
once?: boolean
|
||||
): this;
|
||||
off<T extends EventEmitter.EventNames<EventTypes>>(
|
||||
event: T,
|
||||
fn?: EventEmitter.EventListener<EventTypes, T>,
|
||||
context?: Context,
|
||||
once?: boolean
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Remove all listeners, or those of the specified event.
|
||||
*/
|
||||
removeAllListeners(event?: EventEmitter.EventNames<EventTypes>): this;
|
||||
}
|
||||
|
||||
declare namespace EventEmitter {
|
||||
export interface ListenerFn<Args extends any[] = any[]> {
|
||||
(...args: Args): void;
|
||||
}
|
||||
|
||||
export interface EventEmitterStatic {
|
||||
new <
|
||||
EventTypes extends ValidEventTypes = string | symbol,
|
||||
Context = any
|
||||
>(): EventEmitter<EventTypes, Context>;
|
||||
}
|
||||
|
||||
/**
|
||||
* `object` should be in either of the following forms:
|
||||
* ```
|
||||
* interface EventTypes {
|
||||
* 'event-with-parameters': any[]
|
||||
* 'event-with-example-handler': (...args: any[]) => void
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export type ValidEventTypes = string | symbol | object;
|
||||
|
||||
export type EventNames<T extends ValidEventTypes> = T extends string | symbol
|
||||
? T
|
||||
: keyof T;
|
||||
|
||||
export type ArgumentMap<T extends object> = {
|
||||
[K in keyof T]: T[K] extends (...args: any[]) => void
|
||||
? Parameters<T[K]>
|
||||
: T[K] extends any[]
|
||||
? T[K]
|
||||
: any[];
|
||||
};
|
||||
|
||||
export type EventListener<
|
||||
T extends ValidEventTypes,
|
||||
K extends EventNames<T>
|
||||
> = T extends string | symbol
|
||||
? (...args: any[]) => void
|
||||
: (
|
||||
...args: ArgumentMap<Exclude<T, string | symbol>>[Extract<K, keyof T>]
|
||||
) => void;
|
||||
|
||||
export type EventArgs<
|
||||
T extends ValidEventTypes,
|
||||
K extends EventNames<T>
|
||||
> = Parameters<EventListener<T, K>>;
|
||||
|
||||
export const EventEmitter: EventEmitterStatic;
|
||||
}
|
||||
|
||||
export = EventEmitter;
|
||||
@@ -0,0 +1,336 @@
|
||||
'use strict';
|
||||
|
||||
var has = Object.prototype.hasOwnProperty
|
||||
, prefix = '~';
|
||||
|
||||
/**
|
||||
* Constructor to create a storage for our `EE` objects.
|
||||
* An `Events` instance is a plain object whose properties are event names.
|
||||
*
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
function Events() {}
|
||||
|
||||
//
|
||||
// We try to not inherit from `Object.prototype`. In some engines creating an
|
||||
// instance in this way is faster than calling `Object.create(null)` directly.
|
||||
// If `Object.create(null)` is not supported we prefix the event names with a
|
||||
// character to make sure that the built-in object properties are not
|
||||
// overridden or used as an attack vector.
|
||||
//
|
||||
if (Object.create) {
|
||||
Events.prototype = Object.create(null);
|
||||
|
||||
//
|
||||
// This hack is needed because the `__proto__` property is still inherited in
|
||||
// some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
|
||||
//
|
||||
if (!new Events().__proto__) prefix = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Representation of a single event listener.
|
||||
*
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {*} context The context to invoke the listener with.
|
||||
* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
function EE(fn, context, once) {
|
||||
this.fn = fn;
|
||||
this.context = context;
|
||||
this.once = once || false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener for a given event.
|
||||
*
|
||||
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {*} context The context to invoke the listener with.
|
||||
* @param {Boolean} once Specify if the listener is a one-time listener.
|
||||
* @returns {EventEmitter}
|
||||
* @private
|
||||
*/
|
||||
function addListener(emitter, event, fn, context, once) {
|
||||
if (typeof fn !== 'function') {
|
||||
throw new TypeError('The listener must be a function');
|
||||
}
|
||||
|
||||
var listener = new EE(fn, context || emitter, once)
|
||||
, evt = prefix ? prefix + event : event;
|
||||
|
||||
if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
|
||||
else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
|
||||
else emitter._events[evt] = [emitter._events[evt], listener];
|
||||
|
||||
return emitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear event by name.
|
||||
*
|
||||
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
|
||||
* @param {(String|Symbol)} evt The Event name.
|
||||
* @private
|
||||
*/
|
||||
function clearEvent(emitter, evt) {
|
||||
if (--emitter._eventsCount === 0) emitter._events = new Events();
|
||||
else delete emitter._events[evt];
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimal `EventEmitter` interface that is molded against the Node.js
|
||||
* `EventEmitter` interface.
|
||||
*
|
||||
* @constructor
|
||||
* @public
|
||||
*/
|
||||
function EventEmitter() {
|
||||
this._events = new Events();
|
||||
this._eventsCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array listing the events for which the emitter has registered
|
||||
* listeners.
|
||||
*
|
||||
* @returns {Array}
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.eventNames = function eventNames() {
|
||||
var names = []
|
||||
, events
|
||||
, name;
|
||||
|
||||
if (this._eventsCount === 0) return names;
|
||||
|
||||
for (name in (events = this._events)) {
|
||||
if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
|
||||
}
|
||||
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
return names.concat(Object.getOwnPropertySymbols(events));
|
||||
}
|
||||
|
||||
return names;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the listeners registered for a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @returns {Array} The registered listeners.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.listeners = function listeners(event) {
|
||||
var evt = prefix ? prefix + event : event
|
||||
, handlers = this._events[evt];
|
||||
|
||||
if (!handlers) return [];
|
||||
if (handlers.fn) return [handlers.fn];
|
||||
|
||||
for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
|
||||
ee[i] = handlers[i].fn;
|
||||
}
|
||||
|
||||
return ee;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the number of listeners listening to a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @returns {Number} The number of listeners.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.listenerCount = function listenerCount(event) {
|
||||
var evt = prefix ? prefix + event : event
|
||||
, listeners = this._events[evt];
|
||||
|
||||
if (!listeners) return 0;
|
||||
if (listeners.fn) return 1;
|
||||
return listeners.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls each of the listeners registered for a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @returns {Boolean} `true` if the event had listeners, else `false`.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
|
||||
var evt = prefix ? prefix + event : event;
|
||||
|
||||
if (!this._events[evt]) return false;
|
||||
|
||||
var listeners = this._events[evt]
|
||||
, len = arguments.length
|
||||
, args
|
||||
, i;
|
||||
|
||||
if (listeners.fn) {
|
||||
if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
|
||||
|
||||
switch (len) {
|
||||
case 1: return listeners.fn.call(listeners.context), true;
|
||||
case 2: return listeners.fn.call(listeners.context, a1), true;
|
||||
case 3: return listeners.fn.call(listeners.context, a1, a2), true;
|
||||
case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
|
||||
case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
|
||||
case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
|
||||
}
|
||||
|
||||
for (i = 1, args = new Array(len -1); i < len; i++) {
|
||||
args[i - 1] = arguments[i];
|
||||
}
|
||||
|
||||
listeners.fn.apply(listeners.context, args);
|
||||
} else {
|
||||
var length = listeners.length
|
||||
, j;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
|
||||
|
||||
switch (len) {
|
||||
case 1: listeners[i].fn.call(listeners[i].context); break;
|
||||
case 2: listeners[i].fn.call(listeners[i].context, a1); break;
|
||||
case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
|
||||
case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
|
||||
default:
|
||||
if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
|
||||
args[j - 1] = arguments[j];
|
||||
}
|
||||
|
||||
listeners[i].fn.apply(listeners[i].context, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a listener for a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {*} [context=this] The context to invoke the listener with.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.on = function on(event, fn, context) {
|
||||
return addListener(this, event, fn, context, false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a one-time listener for a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {*} [context=this] The context to invoke the listener with.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.once = function once(event, fn, context) {
|
||||
return addListener(this, event, fn, context, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the listeners of a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @param {Function} fn Only remove the listeners that match this function.
|
||||
* @param {*} context Only remove the listeners that have this context.
|
||||
* @param {Boolean} once Only remove one-time listeners.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
|
||||
var evt = prefix ? prefix + event : event;
|
||||
|
||||
if (!this._events[evt]) return this;
|
||||
if (!fn) {
|
||||
clearEvent(this, evt);
|
||||
return this;
|
||||
}
|
||||
|
||||
var listeners = this._events[evt];
|
||||
|
||||
if (listeners.fn) {
|
||||
if (
|
||||
listeners.fn === fn &&
|
||||
(!once || listeners.once) &&
|
||||
(!context || listeners.context === context)
|
||||
) {
|
||||
clearEvent(this, evt);
|
||||
}
|
||||
} else {
|
||||
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
|
||||
if (
|
||||
listeners[i].fn !== fn ||
|
||||
(once && !listeners[i].once) ||
|
||||
(context && listeners[i].context !== context)
|
||||
) {
|
||||
events.push(listeners[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Reset the array, or remove it completely if we have no more listeners.
|
||||
//
|
||||
if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
|
||||
else clearEvent(this, evt);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove all listeners, or those of the specified event.
|
||||
*
|
||||
* @param {(String|Symbol)} [event] The event name.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
|
||||
var evt;
|
||||
|
||||
if (event) {
|
||||
evt = prefix ? prefix + event : event;
|
||||
if (this._events[evt]) clearEvent(this, evt);
|
||||
} else {
|
||||
this._events = new Events();
|
||||
this._eventsCount = 0;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
//
|
||||
// Alias methods names because people roll like that.
|
||||
//
|
||||
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
||||
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
|
||||
|
||||
//
|
||||
// Expose the prefix.
|
||||
//
|
||||
EventEmitter.prefixed = prefix;
|
||||
|
||||
//
|
||||
// Allow `EventEmitter` to be imported as module namespace.
|
||||
//
|
||||
EventEmitter.EventEmitter = EventEmitter;
|
||||
|
||||
//
|
||||
// Expose the module.
|
||||
//
|
||||
if ('undefined' !== typeof module) {
|
||||
module.exports = EventEmitter;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "eventemitter3",
|
||||
"version": "4.0.7",
|
||||
"description": "EventEmitter3 focuses on performance while maintaining a Node.js AND browser compatible interface.",
|
||||
"main": "index.js",
|
||||
"typings": "index.d.ts",
|
||||
"scripts": {
|
||||
"browserify": "rm -rf umd && mkdir umd && browserify index.js -s EventEmitter3 -o umd/eventemitter3.js",
|
||||
"minify": "uglifyjs umd/eventemitter3.js --source-map -cm -o umd/eventemitter3.min.js",
|
||||
"benchmark": "find benchmarks/run -name '*.js' -exec benchmarks/start.sh {} \\;",
|
||||
"test": "nyc --reporter=html --reporter=text mocha test/test.js",
|
||||
"prepublishOnly": "npm run browserify && npm run minify",
|
||||
"test-browser": "node test/browser.js"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"umd"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/primus/eventemitter3.git"
|
||||
},
|
||||
"keywords": [
|
||||
"EventEmitter",
|
||||
"EventEmitter2",
|
||||
"EventEmitter3",
|
||||
"Events",
|
||||
"addEventListener",
|
||||
"addListener",
|
||||
"emit",
|
||||
"emits",
|
||||
"emitter",
|
||||
"event",
|
||||
"once",
|
||||
"pub/sub",
|
||||
"publish",
|
||||
"reactor",
|
||||
"subscribe"
|
||||
],
|
||||
"author": "Arnout Kazemier",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/primus/eventemitter3/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"assume": "^2.2.0",
|
||||
"browserify": "^16.5.0",
|
||||
"mocha": "^8.0.1",
|
||||
"nyc": "^15.1.0",
|
||||
"pre-commit": "^1.2.0",
|
||||
"sauce-browsers": "^2.0.0",
|
||||
"sauce-test": "^1.3.3",
|
||||
"uglify-js": "^3.9.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.EventEmitter3 = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var has = Object.prototype.hasOwnProperty
|
||||
, prefix = '~';
|
||||
|
||||
/**
|
||||
* Constructor to create a storage for our `EE` objects.
|
||||
* An `Events` instance is a plain object whose properties are event names.
|
||||
*
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
function Events() {}
|
||||
|
||||
//
|
||||
// We try to not inherit from `Object.prototype`. In some engines creating an
|
||||
// instance in this way is faster than calling `Object.create(null)` directly.
|
||||
// If `Object.create(null)` is not supported we prefix the event names with a
|
||||
// character to make sure that the built-in object properties are not
|
||||
// overridden or used as an attack vector.
|
||||
//
|
||||
if (Object.create) {
|
||||
Events.prototype = Object.create(null);
|
||||
|
||||
//
|
||||
// This hack is needed because the `__proto__` property is still inherited in
|
||||
// some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
|
||||
//
|
||||
if (!new Events().__proto__) prefix = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Representation of a single event listener.
|
||||
*
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {*} context The context to invoke the listener with.
|
||||
* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
function EE(fn, context, once) {
|
||||
this.fn = fn;
|
||||
this.context = context;
|
||||
this.once = once || false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener for a given event.
|
||||
*
|
||||
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {*} context The context to invoke the listener with.
|
||||
* @param {Boolean} once Specify if the listener is a one-time listener.
|
||||
* @returns {EventEmitter}
|
||||
* @private
|
||||
*/
|
||||
function addListener(emitter, event, fn, context, once) {
|
||||
if (typeof fn !== 'function') {
|
||||
throw new TypeError('The listener must be a function');
|
||||
}
|
||||
|
||||
var listener = new EE(fn, context || emitter, once)
|
||||
, evt = prefix ? prefix + event : event;
|
||||
|
||||
if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
|
||||
else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
|
||||
else emitter._events[evt] = [emitter._events[evt], listener];
|
||||
|
||||
return emitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear event by name.
|
||||
*
|
||||
* @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
|
||||
* @param {(String|Symbol)} evt The Event name.
|
||||
* @private
|
||||
*/
|
||||
function clearEvent(emitter, evt) {
|
||||
if (--emitter._eventsCount === 0) emitter._events = new Events();
|
||||
else delete emitter._events[evt];
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimal `EventEmitter` interface that is molded against the Node.js
|
||||
* `EventEmitter` interface.
|
||||
*
|
||||
* @constructor
|
||||
* @public
|
||||
*/
|
||||
function EventEmitter() {
|
||||
this._events = new Events();
|
||||
this._eventsCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array listing the events for which the emitter has registered
|
||||
* listeners.
|
||||
*
|
||||
* @returns {Array}
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.eventNames = function eventNames() {
|
||||
var names = []
|
||||
, events
|
||||
, name;
|
||||
|
||||
if (this._eventsCount === 0) return names;
|
||||
|
||||
for (name in (events = this._events)) {
|
||||
if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
|
||||
}
|
||||
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
return names.concat(Object.getOwnPropertySymbols(events));
|
||||
}
|
||||
|
||||
return names;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the listeners registered for a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @returns {Array} The registered listeners.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.listeners = function listeners(event) {
|
||||
var evt = prefix ? prefix + event : event
|
||||
, handlers = this._events[evt];
|
||||
|
||||
if (!handlers) return [];
|
||||
if (handlers.fn) return [handlers.fn];
|
||||
|
||||
for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
|
||||
ee[i] = handlers[i].fn;
|
||||
}
|
||||
|
||||
return ee;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the number of listeners listening to a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @returns {Number} The number of listeners.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.listenerCount = function listenerCount(event) {
|
||||
var evt = prefix ? prefix + event : event
|
||||
, listeners = this._events[evt];
|
||||
|
||||
if (!listeners) return 0;
|
||||
if (listeners.fn) return 1;
|
||||
return listeners.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls each of the listeners registered for a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @returns {Boolean} `true` if the event had listeners, else `false`.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
|
||||
var evt = prefix ? prefix + event : event;
|
||||
|
||||
if (!this._events[evt]) return false;
|
||||
|
||||
var listeners = this._events[evt]
|
||||
, len = arguments.length
|
||||
, args
|
||||
, i;
|
||||
|
||||
if (listeners.fn) {
|
||||
if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
|
||||
|
||||
switch (len) {
|
||||
case 1: return listeners.fn.call(listeners.context), true;
|
||||
case 2: return listeners.fn.call(listeners.context, a1), true;
|
||||
case 3: return listeners.fn.call(listeners.context, a1, a2), true;
|
||||
case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
|
||||
case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
|
||||
case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
|
||||
}
|
||||
|
||||
for (i = 1, args = new Array(len -1); i < len; i++) {
|
||||
args[i - 1] = arguments[i];
|
||||
}
|
||||
|
||||
listeners.fn.apply(listeners.context, args);
|
||||
} else {
|
||||
var length = listeners.length
|
||||
, j;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
|
||||
|
||||
switch (len) {
|
||||
case 1: listeners[i].fn.call(listeners[i].context); break;
|
||||
case 2: listeners[i].fn.call(listeners[i].context, a1); break;
|
||||
case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
|
||||
case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
|
||||
default:
|
||||
if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
|
||||
args[j - 1] = arguments[j];
|
||||
}
|
||||
|
||||
listeners[i].fn.apply(listeners[i].context, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a listener for a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {*} [context=this] The context to invoke the listener with.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.on = function on(event, fn, context) {
|
||||
return addListener(this, event, fn, context, false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a one-time listener for a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {*} [context=this] The context to invoke the listener with.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.once = function once(event, fn, context) {
|
||||
return addListener(this, event, fn, context, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the listeners of a given event.
|
||||
*
|
||||
* @param {(String|Symbol)} event The event name.
|
||||
* @param {Function} fn Only remove the listeners that match this function.
|
||||
* @param {*} context Only remove the listeners that have this context.
|
||||
* @param {Boolean} once Only remove one-time listeners.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
|
||||
var evt = prefix ? prefix + event : event;
|
||||
|
||||
if (!this._events[evt]) return this;
|
||||
if (!fn) {
|
||||
clearEvent(this, evt);
|
||||
return this;
|
||||
}
|
||||
|
||||
var listeners = this._events[evt];
|
||||
|
||||
if (listeners.fn) {
|
||||
if (
|
||||
listeners.fn === fn &&
|
||||
(!once || listeners.once) &&
|
||||
(!context || listeners.context === context)
|
||||
) {
|
||||
clearEvent(this, evt);
|
||||
}
|
||||
} else {
|
||||
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
|
||||
if (
|
||||
listeners[i].fn !== fn ||
|
||||
(once && !listeners[i].once) ||
|
||||
(context && listeners[i].context !== context)
|
||||
) {
|
||||
events.push(listeners[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Reset the array, or remove it completely if we have no more listeners.
|
||||
//
|
||||
if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
|
||||
else clearEvent(this, evt);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove all listeners, or those of the specified event.
|
||||
*
|
||||
* @param {(String|Symbol)} [event] The event name.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @public
|
||||
*/
|
||||
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
|
||||
var evt;
|
||||
|
||||
if (event) {
|
||||
evt = prefix ? prefix + event : event;
|
||||
if (this._events[evt]) clearEvent(this, evt);
|
||||
} else {
|
||||
this._events = new Events();
|
||||
this._eventsCount = 0;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
//
|
||||
// Alias methods names because people roll like that.
|
||||
//
|
||||
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
||||
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
|
||||
|
||||
//
|
||||
// Expose the prefix.
|
||||
//
|
||||
EventEmitter.prefixed = prefix;
|
||||
|
||||
//
|
||||
// Allow `EventEmitter` to be imported as module namespace.
|
||||
//
|
||||
EventEmitter.EventEmitter = EventEmitter;
|
||||
|
||||
//
|
||||
// Expose the module.
|
||||
//
|
||||
if ('undefined' !== typeof module) {
|
||||
module.exports = EventEmitter;
|
||||
}
|
||||
|
||||
},{}]},{},[1])(1)
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
!function(e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).EventEmitter3=e()}(function(){return function i(s,f,c){function u(t,e){if(!f[t]){if(!s[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(a)return a(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var o=f[t]={exports:{}};s[t][0].call(o.exports,function(e){return u(s[t][1][e]||e)},o,o.exports,i,s,f,c)}return f[t].exports}for(var a="function"==typeof require&&require,e=0;e<c.length;e++)u(c[e]);return u}({1:[function(e,t,n){"use strict";var r=Object.prototype.hasOwnProperty,v="~";function o(){}function f(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function i(e,t,n,r,o){if("function"!=typeof n)throw new TypeError("The listener must be a function");var i=new f(n,r||e,o),s=v?v+t:t;return e._events[s]?e._events[s].fn?e._events[s]=[e._events[s],i]:e._events[s].push(i):(e._events[s]=i,e._eventsCount++),e}function u(e,t){0==--e._eventsCount?e._events=new o:delete e._events[t]}function s(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(v=!1)),s.prototype.eventNames=function(){var e,t,n=[];if(0===this._eventsCount)return n;for(t in e=this._events)r.call(e,t)&&n.push(v?t.slice(1):t);return Object.getOwnPropertySymbols?n.concat(Object.getOwnPropertySymbols(e)):n},s.prototype.listeners=function(e){var t=v?v+e:e,n=this._events[t];if(!n)return[];if(n.fn)return[n.fn];for(var r=0,o=n.length,i=new Array(o);r<o;r++)i[r]=n[r].fn;return i},s.prototype.listenerCount=function(e){var t=v?v+e:e,n=this._events[t];return n?n.fn?1:n.length:0},s.prototype.emit=function(e,t,n,r,o,i){var s=v?v+e:e;if(!this._events[s])return!1;var f,c=this._events[s],u=arguments.length;if(c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),u){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,t),!0;case 3:return c.fn.call(c.context,t,n),!0;case 4:return c.fn.call(c.context,t,n,r),!0;case 5:return c.fn.call(c.context,t,n,r,o),!0;case 6:return c.fn.call(c.context,t,n,r,o,i),!0}for(p=1,f=new Array(u-1);p<u;p++)f[p-1]=arguments[p];c.fn.apply(c.context,f)}else for(var a,l=c.length,p=0;p<l;p++)switch(c[p].once&&this.removeListener(e,c[p].fn,void 0,!0),u){case 1:c[p].fn.call(c[p].context);break;case 2:c[p].fn.call(c[p].context,t);break;case 3:c[p].fn.call(c[p].context,t,n);break;case 4:c[p].fn.call(c[p].context,t,n,r);break;default:if(!f)for(a=1,f=new Array(u-1);a<u;a++)f[a-1]=arguments[a];c[p].fn.apply(c[p].context,f)}return!0},s.prototype.on=function(e,t,n){return i(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return i(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,n,r){var o=v?v+e:e;if(!this._events[o])return this;if(!t)return u(this,o),this;var i=this._events[o];if(i.fn)i.fn!==t||r&&!i.once||n&&i.context!==n||u(this,o);else{for(var s=0,f=[],c=i.length;s<c;s++)(i[s].fn!==t||r&&!i[s].once||n&&i[s].context!==n)&&f.push(i[s]);f.length?this._events[o]=1===f.length?f[0]:f:u(this,o)}return this},s.prototype.removeAllListeners=function(e){var t;return e?(t=v?v+e:e,this._events[t]&&u(this,t)):(this._events=new o,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=v,s.EventEmitter=s,void 0!==t&&(t.exports=s)},{}]},{},[1])(1)});
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "@trtc/call-engine-lite-wx",
|
||||
"version": "3.4.13",
|
||||
"description": "Tencent Cloud TUICallEngine SDK for Wechat",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Tencent-RTC/rtc-call-engine/tree/main/Web"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tencentcloud/lite-chat": "^1.5.0",
|
||||
"eventemitter3": "^4.0.7",
|
||||
"@tencentcloud/trtc-component-wx": "^1.0.5"
|
||||
},
|
||||
"author": "Tencent Cloud Terminal R&D Center",
|
||||
"keywords": [
|
||||
"call",
|
||||
"video call",
|
||||
"audio call",
|
||||
"video",
|
||||
"audio",
|
||||
"TRTC",
|
||||
"camera",
|
||||
"microphone",
|
||||
"webrtc",
|
||||
"real-time communication",
|
||||
"javascript",
|
||||
"rtc"
|
||||
],
|
||||
"license": "ISC"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
# TUICallkit 组件接入说明
|
||||
TUICallkit 是小程序音视频通话 UI 组件,通过编写几行代码,就可以为您的小程序应用添加音视频通话功能。
|
||||
|
||||
**低于 v3.0.4 版本,参考的 [readme](https://www.npmjs.com/package/@tencentcloud/call-uikit-wx/v/1.4.4)。**
|
||||
|
||||
## 环境准备
|
||||
|
||||
- 微信 App iOS 最低版本要求:8.0.40
|
||||
- 微信 App Android 最低版本要求:8.0.40
|
||||
- 小程序基础库最低版本要求:2.10.0
|
||||
- 由于小程序测试号不具备 live-pusher 和 live-player 的使用权限,请使用企业小程序账号申请相关权限进行开发
|
||||
- 由于微信开发者工具不支持原生组件(即 live-pusher 和 live-player 标签),需要在真机上进行运行体验
|
||||
|
||||
## 特性
|
||||
- ⚡️ 功能全面 —— 支持单人/多人/音频/视频通话、支持视频转音频通话、支持自由选择通话设备
|
||||
- 🎨 灵活样式 —— 组件开源,可复用逻辑,自定义 UI 样式
|
||||
- 🛠 优秀生态 —— 与 [TUIKit](https://cloud.tencent.com/document/product/269/79737) 协同使用,可以在 [TIM](https://cloud.tencent.com/document/product/269) 会话中直接发起音视频通话
|
||||
- 🌍 跨平台 —— 支持 Android、iOS、Web、小程序、Flutter、UniApp 等 [多个开发平台](https://cloud.tencent.com/document/product/647/78742)
|
||||
- ☁️ 低延迟 —— 腾讯云全球链路资源储备,保证国际链路端到端平均时延 < 300ms
|
||||
- 🤙🏻 低卡顿 —— 抗丢包率超过 80%、抗网络抖动超过 1000ms,弱网环境仍顺畅稳定
|
||||
- 🌈 高品质 —— 支持 720P、1080P 高清画质,70% 丢包率仍可正常视频
|
||||
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
TUICallkit
|
||||
├─ debug // 用来本地测试时生成 userSig
|
||||
├─ src // UI 组件源码
|
||||
├─ Components // 呼叫中 UI 组件
|
||||
└─ TUICallService // UI 组件的逻辑
|
||||
└─ adapter-vue.ts // 用来适配 vue2、vue3 的适配层
|
||||
└─ index.ts // UI 组件逻辑的入口
|
||||
├─ types
|
||||
├─ package.json
|
||||
├─ README.md
|
||||
├─ tuicall-uikit-vue.es.js
|
||||
├─ tuicall-uikit-vue.umd.js
|
||||
```
|
||||
|
||||
|
||||
## 使用指引
|
||||
为方便您的使用,本组件配套多篇使用指引:
|
||||
- 如果您想要了解 TUICallKit,请阅读 [组件介绍 TUICallKit](https://cloud.tencent.com/document/product/647/78742)。
|
||||
- 如果您想把我们的功能直接嵌入到您的项目中,请阅读 [快速接入 TUICallKit](https://cloud.tencent.com/document/product/647/78912)。
|
||||
- 如果您想要了解详细 API,请阅读 [API 概览](https://cloud.tencent.com/document/product/647/78759)。
|
||||
|
||||
## 附录
|
||||
|
||||
- 如果你遇到了困难,可以先参阅 [常见问题](https://cloud.tencent.com/document/product/647/78733)。
|
||||
- 如果发现了示例代码的 bug,欢迎提交 issue。
|
||||
- 欢迎加入 QQ 群:**646165204**,进行技术交流和反馈~
|
||||
-
|
||||
@@ -0,0 +1,26 @@
|
||||
import LibGenerateTestUserSig from './lib-generate-test-usersig-es.min.js';
|
||||
|
||||
let SDKAPPID = 0;
|
||||
|
||||
let SECRETKEY = '';
|
||||
|
||||
/**
|
||||
* Expiration time for the signature, it is recommended not to set it too short.
|
||||
* Time unit: seconds
|
||||
* Default time: 7 x 24 x 60 x 60 = 604800 = 7 days
|
||||
*/
|
||||
const EXPIRETIME = 604800;
|
||||
|
||||
export function genTestUserSig({ userID, SDKAppID, SecretKey }) {
|
||||
if (SDKAppID) SDKAPPID = SDKAppID;
|
||||
if (SecretKey) SECRETKEY = SecretKey;
|
||||
const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME);
|
||||
const userSig = generator.genTestUserSig(userID);
|
||||
|
||||
return {
|
||||
SDKAppID: SDKAPPID,
|
||||
userSig,
|
||||
};
|
||||
}
|
||||
|
||||
export default genTestUserSig;
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "@trtc/calls-uikit-wx-uniapp",
|
||||
"version": "4.2.7",
|
||||
"main": "./tuicall-uikit-vue.umd.js",
|
||||
"module": "./tuicall-uikit-vue.es.js",
|
||||
"types": "./types/index.d.ts",
|
||||
"description": "An Open-source Voice & Video Calling UI Component Based on Tencent Cloud Service.",
|
||||
"homepage": "https://cloud.tencent.com/document/product/647/78912",
|
||||
"license": "ISC",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tencentyun/TUICallKit/tree/main/uni-app/TUICallKit-Miniprogram",
|
||||
"directory": "Web"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tencentcloud/lite-chat": "^1.5.0",
|
||||
"@tencentcloud/tui-core-lite": "1.0.0",
|
||||
"@trtc/call-engine-lite-wx": "~3.4.10",
|
||||
"@tencentcloud/trtc-component-uniapp": "^1.0.4"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/tencentyun/TUICallKit/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"call",
|
||||
"video call",
|
||||
"audio call",
|
||||
"callkit",
|
||||
"uikit",
|
||||
"call uikit",
|
||||
"video",
|
||||
"audio",
|
||||
"TRTC",
|
||||
"camera",
|
||||
"microphone",
|
||||
"webrtc",
|
||||
"real-time communication",
|
||||
"javascript",
|
||||
"rtc",
|
||||
"语音",
|
||||
"视频",
|
||||
"电话",
|
||||
"通话"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
<template>
|
||||
<div v-if="callInfoContextValue.callStatus !== CallStatus.IDLE" :style="[{ visibility: floatWindowContextValue.isFloatWindow ? 'hidden' : '' }]" id="tuicallkit-id" :class="[bodyStyle, miniMizedDeskStyle, mobileVideoStyle, mobileAudioStyle]">
|
||||
<SingleCall v-if="!callInfoContextValue.isGroupCall" class="singCall"></SingleCall>
|
||||
<GroupCall v-else class="singCall"></GroupCall>
|
||||
<AISubtitle />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, reactive, onUnmounted, toRefs, watchEffect, provide } from '../adapter-vue';
|
||||
import SingleCall from './components/SingleCall/SingleCall.vue';
|
||||
import GroupCall from './components/GroupCall/GroupCall.vue';
|
||||
import { TUIGlobal, TUIStore, StoreName, TUICallKitAPI, NAME, CallStatus, CallMediaType, VideoDisplayMode, VideoResolution } from '../TUICallService/index';
|
||||
import {
|
||||
CallInfoContextKey,
|
||||
CallerUserInfoContextKey,
|
||||
UserInfoExcludeVolumeContextKey,
|
||||
FloatWindowContextKey,
|
||||
TCallerUserInfoValue,
|
||||
TFloatWindowContextValue,
|
||||
CustomUIConfigContextKey,
|
||||
translateContextKey,
|
||||
} from './context';
|
||||
import { isEmpty } from './util/isEmpty';
|
||||
const isMobile = !TUIGlobal.isPC;
|
||||
const bodyStyle = isMobile ? 'TUICallKit-mobile transition-animation' : 'TUICallKit-desktop';
|
||||
const miniMizedDeskStyle = ref('');
|
||||
const mobileAudioStyle = ref('');
|
||||
const mobileVideoStyle = ref('');
|
||||
const isShowFloatWindow = ref(false);
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
beforeCalling?: (...args: any[]) => void;
|
||||
afterCalling?: (...args: any[]) => void;
|
||||
onMinimized?: (...args: any[]) => void;
|
||||
onMessageSentByMe?: (...args: any[]) => void;
|
||||
kickedOut?: (...args: any[]) => void;
|
||||
statusChanged?: (...args: any[]) => void;
|
||||
allowedMinimized?: boolean;
|
||||
allowedFullScreen?: boolean;
|
||||
videoDisplayMode?: string;
|
||||
videoResolution?: string;
|
||||
}>(),
|
||||
{
|
||||
allowedMinimized: false,
|
||||
allowedFullScreen: true,
|
||||
videoDisplayMode: VideoDisplayMode.COVER,
|
||||
videoResolution: VideoResolution.RESOLUTION_720P,
|
||||
},
|
||||
);
|
||||
|
||||
const callStatus = ref(TUIStore.getData(StoreName.CALL, NAME.CALL_STATUS));
|
||||
const callRole = ref(TUIStore.getData(StoreName.CALL, NAME.CALL_ROLE));
|
||||
const callType = ref(TUIStore.getData(StoreName.CALL, NAME.CALL_MEDIA_TYPE));
|
||||
const isGroupCall = ref(TUIStore.getData(StoreName.CALL, NAME.IS_GROUP));
|
||||
const isEarPhone = ref(TUIStore.getData(StoreName.CALL, NAME.IS_EAR_PHONE));
|
||||
const focusElement = ref(null);
|
||||
const localUserInfoExcludeVolume = ref(TUIStore.getData(StoreName.CALL, NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN));
|
||||
const remoteUserListExcludeVolume = ref(TUIStore.getData(StoreName.CALL, NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST));
|
||||
const callerUserInfo = ref(TUIStore.getData(StoreName.CALL, NAME.CALLER_USER_INFO));
|
||||
const isFloatWindow = ref(TUIStore.getData(StoreName.CALL, NAME.IS_MINIMIZED));
|
||||
const enableVirtualBackground = ref(TUIStore.getData(StoreName.CALL, NAME.ENABLE_VIRTUAL_BACKGROUND));
|
||||
const isShowEnableVirtualBackground = ref(TUIStore.getData(StoreName.CALL, NAME.IS_SHOW_ENABLE_VIRTUAL_BACKGROUND));
|
||||
const customUIConfigContextValue = ref(TUIStore.getData(StoreName.CALL, NAME.CUSTOM_UI_CONFIG));
|
||||
const isMuteSpeaker = ref(TUIStore.getData(StoreName.CALL, NAME.IS_MUTE_SPEAKER));
|
||||
const translate = ref(TUIStore.getData(StoreName.CALL, NAME.TRANSLATE));
|
||||
const callInfoContextValue = reactive({
|
||||
callStatus,
|
||||
callRole,
|
||||
callType,
|
||||
isGroupCall,
|
||||
isEarPhone,
|
||||
focusElement,
|
||||
allowedFullScreen: props.allowedFullScreen,
|
||||
enableVirtualBackground,
|
||||
isShowEnableVirtualBackground,
|
||||
isMuteSpeaker,
|
||||
});
|
||||
const callerUserInfoValue: TCallerUserInfoValue = reactive({ callerUserInfo });
|
||||
const userInfoExcludeVolumeContextValue = reactive({
|
||||
localUserInfoExcludeVolume,
|
||||
remoteUserListExcludeVolume,
|
||||
});
|
||||
const floatWindowContextValue: TFloatWindowContextValue = reactive({ isFloatWindow });
|
||||
const translateContextValue = ref(translate);
|
||||
|
||||
const {
|
||||
beforeCalling,
|
||||
afterCalling,
|
||||
onMinimized,
|
||||
onMessageSentByMe,
|
||||
videoDisplayMode,
|
||||
videoResolution,
|
||||
kickedOut,
|
||||
statusChanged,
|
||||
allowedMinimized,
|
||||
} = toRefs(props);
|
||||
|
||||
const handleCallStatusChange = (value) => {
|
||||
callInfoContextValue.callStatus = value;
|
||||
};
|
||||
const handleIsGroupChange = (value) => {
|
||||
callInfoContextValue.isGroupCall = value;
|
||||
};
|
||||
const handleToastInfoChange = (value) => {
|
||||
if (typeof value === 'object') {
|
||||
const { content, type = 'info' } = value;
|
||||
!isEmpty(content) && showToast(translate.value(content), type);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCallMediaTypeChange = (value) => {
|
||||
callInfoContextValue.callType = value;
|
||||
if (isMobile && isShowFloatWindow.value) {
|
||||
mobileVideoStyle.value = 'miniMized-mobile-audio';
|
||||
mobileAudioStyle.value = '';
|
||||
}
|
||||
|
||||
if (isMobile && !isShowFloatWindow.value) {
|
||||
mobileAudioStyle.value = 'mobile-audio';
|
||||
}
|
||||
};
|
||||
|
||||
const handleIsMinimizedChange = (value) => {
|
||||
floatWindowContextValue.isFloatWindow = value;
|
||||
// 开启悬浮窗
|
||||
if (value) {
|
||||
if (!isMobile) {
|
||||
miniMizedDeskStyle.value = 'miniMized';
|
||||
} else {
|
||||
if (callInfoContextValue.callType === CallMediaType.AUDIO) {
|
||||
mobileAudioStyle.value = 'miniMized-mobile-audio';
|
||||
} else {
|
||||
mobileVideoStyle.value = 'miniMized-mobile-video';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 关闭悬浮窗
|
||||
mobileAudioStyle.value = 'mobile-audio';
|
||||
miniMizedDeskStyle.value = '';
|
||||
mobileVideoStyle.value = '';
|
||||
}
|
||||
};
|
||||
|
||||
const handlePermissionErrorTipChange = (data) => {
|
||||
};
|
||||
const handleCallRoleChange = (value) => {
|
||||
callInfoContextValue.callRole = value;
|
||||
};
|
||||
const handleLocalUserInfoChange = (value) => {
|
||||
userInfoExcludeVolumeContextValue.localUserInfoExcludeVolume = value;
|
||||
};
|
||||
const handleRemoteUserInfoListChange = (value) => {
|
||||
userInfoExcludeVolumeContextValue.remoteUserListExcludeVolume = [...value];
|
||||
};
|
||||
const handleCallerUserInfoChange = (value) => {
|
||||
callerUserInfoValue.callerUserInfo = value;
|
||||
};
|
||||
const handEarPhoneChange = (value) => {
|
||||
callInfoContextValue.isEarPhone = value;
|
||||
};
|
||||
const handleEnableVirtualBackgroundChange = (value) => {
|
||||
callInfoContextValue.enableVirtualBackground = value;
|
||||
};
|
||||
const handleIsShowEnableVirtualBackgroundChange = (value) => {
|
||||
callInfoContextValue.isShowEnableVirtualBackground = value;
|
||||
};
|
||||
const handleCustomUIConfigChange = (value) => {
|
||||
customUIConfigContextValue.value = value;
|
||||
};
|
||||
const handleMuteSpeakerChange = (value) => {
|
||||
callInfoContextValue.isMuteSpeaker = value;
|
||||
};
|
||||
const handleTranslateChange = (value) => {
|
||||
translate.value = value;
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
TUICallKitAPI.setCallback({
|
||||
beforeCalling: beforeCalling && beforeCalling.value,
|
||||
afterCalling: afterCalling && afterCalling.value,
|
||||
onMinimized: onMinimized && onMinimized.value,
|
||||
onMessageSentByMe: onMessageSentByMe && onMessageSentByMe.value,
|
||||
kickedOut: kickedOut && kickedOut.value,
|
||||
statusChanged: statusChanged && statusChanged.value,
|
||||
});
|
||||
});
|
||||
|
||||
const watchOptions = {
|
||||
[NAME.CALL_STATUS]: handleCallStatusChange,
|
||||
[NAME.IS_GROUP]: handleIsGroupChange,
|
||||
[NAME.TOAST_INFO]: handleToastInfoChange,
|
||||
[NAME.CALL_MEDIA_TYPE]: handleCallMediaTypeChange,
|
||||
[NAME.SHOW_PERMISSION_TIP]: handlePermissionErrorTipChange,
|
||||
[NAME.CALL_ROLE]: handleCallRoleChange,
|
||||
[NAME.LOCAL_USER_INFO_EXCLUDE_VOLUMN]: handleLocalUserInfoChange,
|
||||
[NAME.REMOTE_USER_INFO_EXCLUDE_VOLUMN_LIST]: handleRemoteUserInfoListChange,
|
||||
[NAME.CALLER_USER_INFO]: handleCallerUserInfoChange,
|
||||
[NAME.IS_EAR_PHONE]: handEarPhoneChange,
|
||||
[NAME.ENABLE_VIRTUAL_BACKGROUND]: handleEnableVirtualBackgroundChange,
|
||||
[NAME.IS_SHOW_ENABLE_VIRTUAL_BACKGROUND]: handleIsShowEnableVirtualBackgroundChange,
|
||||
[NAME.CUSTOM_UI_CONFIG]: handleCustomUIConfigChange,
|
||||
[NAME.IS_MUTE_SPEAKER]: handleMuteSpeakerChange,
|
||||
[NAME.TRANSLATE]: handleTranslateChange,
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if(allowedMinimized.value){
|
||||
TUICallKitAPI.enableFloatWindow(allowedMinimized.value)
|
||||
}
|
||||
TUICallKitAPI.setVideoDisplayMode(videoDisplayMode.value as any);
|
||||
TUICallKitAPI.setVideoResolution(videoResolution.value as any);
|
||||
TUIStore.watch(
|
||||
StoreName.CALL,
|
||||
watchOptions,
|
||||
{
|
||||
notifyRangeWhenWatch: NAME.MYSELF,
|
||||
},
|
||||
);
|
||||
TUIStore.watch(StoreName.CALL, {
|
||||
[NAME.IS_MINIMIZED]: handleIsMinimizedChange,
|
||||
});
|
||||
});
|
||||
|
||||
function showToast(value: string, type: string) {
|
||||
switch (type) {
|
||||
case 'info':
|
||||
uni.showToast({
|
||||
title: value,
|
||||
icon: 'none',
|
||||
});
|
||||
break;
|
||||
case 'error':
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onUnmounted(async () => {
|
||||
TUIStore.unwatch(StoreName.CALL, {
|
||||
...watchOptions,
|
||||
[NAME.IS_MINIMIZED]: handleIsMinimizedChange,
|
||||
});
|
||||
await TUICallKitAPI.handleExceptionExit();
|
||||
});
|
||||
|
||||
provide(CallInfoContextKey, callInfoContextValue);
|
||||
provide(CallerUserInfoContextKey, callerUserInfoValue);
|
||||
provide(UserInfoExcludeVolumeContextKey, userInfoExcludeVolumeContextValue);
|
||||
provide(FloatWindowContextKey, floatWindowContextValue);
|
||||
provide(CustomUIConfigContextKey, customUIConfigContextValue);
|
||||
provide(translateContextKey, translateContextValue);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.TUICallKit-mobile {
|
||||
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
|
||||
.singCall {
|
||||
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
.transition-animation {
|
||||
transform: translateY(-100%);
|
||||
animation: slideInDown 0.5s ease forwards;
|
||||
}
|
||||
|
||||
@keyframes slideInDown {
|
||||
from {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.TUICallKit-desktop {
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
position: relative;
|
||||
border-radius: inherit;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: white;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
z-index: 12;
|
||||
border-radius: 16px;
|
||||
|
||||
.singCall {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-audio {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.miniMized {
|
||||
width: 168px !important;
|
||||
height: 56px !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.miniMized-mobile-audio {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
position: fixed;
|
||||
top: 40px;
|
||||
right: 40px;
|
||||
}
|
||||
|
||||
.miniMized-mobile-video {
|
||||
width: 40%;
|
||||
height: 30%;
|
||||
position: fixed;
|
||||
top: 40px;
|
||||
right: 40px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.73708 12.9963C8.71266 12.8344 8.7 12.6687 8.7 12.5V6C8.7 4.17746 10.1775 2.7 12 2.7C13.5488 2.7 14.8484 3.76695 15.2038 5.20592L16.4458 3.70974C15.615 2.10033 13.936 1 12 1C9.23858 1 7 3.23858 7 6V12.5C7 13.2333 7.15786 13.9297 7.44145 14.5572L8.73708 12.9963ZM11.3385 15.7337L10.1618 17.1513C10.7308 17.3763 11.3509 17.5 12 17.5C14.7614 17.5 17 15.2614 17 12.5V8.9133L15.3 10.9613V12.5C15.3 14.3225 13.8225 15.8 12 15.8C11.7734 15.8 11.5522 15.7772 11.3385 15.7337ZM5.96519 16.3356C5.25933 15.2273 4.85039 13.9114 4.85039 12.5V11H3.15039V12.5C3.15039 14.4416 3.77562 16.2371 4.83572 17.6963L5.96519 16.3356ZM7.63218 20.1986L8.7394 18.8647C9.71718 19.3667 10.8257 19.65 12.0004 19.65C15.9492 19.65 19.1504 16.4488 19.1504 12.5V11H20.8504V12.5C20.8504 17.0498 17.4171 20.7976 13 21.2942V24H11V21.2941C9.78613 21.1575 8.64658 20.7754 7.63218 20.1986Z" fill="#fff" />
|
||||
<path d="M5.73682 19.5513L18.2667 4.46371" stroke="#ED414D" style="stroke:#ED414D;stroke:color(display-p3 0.9292 0.2555 0.3004);stroke-opacity:1;" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<rect x="11" y="20" width="2" height="4" fill="#fff" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.1499 11V12.5C3.1499 17.3877 7.11218 21.35 11.9999 21.35C16.8876 21.35 20.8499 17.3877 20.8499 12.5V11H19.1499V12.5C19.1499 16.4488 15.9487 19.65 11.9999 19.65C8.05107 19.65 4.8499 16.4488 4.8499 12.5V11H3.1499Z" fill="#fff"/>
|
||||
<rect x="7.85" y="1.85" width="8.3" height="14.8" rx="4.15" stroke="#fff" stroke-width="1.7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 537 B |
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="m557.2 512 233.4-233.4c12.5-12.5 12.5-32.8 0-45.2s-32.8-12.5-45.2 0L512 466.8 278.6 233.4c-12.5-12.5-32.8-12.5-45.2 0s-12.5 32.8 0 45.2L466.8 512 233.4 745.4c-12.5 12.5-12.5 32.8 0 45.2 6.2 6.2 14.4 9.4 22.6 9.4s16.4-3.1 22.6-9.4L512 557.2l233.4 233.4c6.2 6.2 14.4 9.4 22.6 9.4s16.4-3.1 22.6-9.4c12.5-12.5 12.5-32.8 0-45.2L557.2 512z"/></svg>
|
||||
|
After Width: | Height: | Size: 451 B |
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M512 97.524c228.913 0 414.476 185.563 414.476 414.476S740.913 926.476 512 926.476 97.524 740.913 97.524 512 283.087 97.524 512 97.524zM641.292 330.97 512.024 460.264 382.708 330.97l-51.737 51.737 129.317 129.268-129.317 129.316 51.737 51.737L512 563.688l129.292 129.316 51.737-51.736L563.688 512l129.316-129.292-51.736-51.737z" fill="#d54941"/></svg>
|
||||
|
After Width: | Height: | Size: 459 B |
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M512 97.524c228.913 0 414.476 185.563 414.476 414.476S740.913 926.476 512 926.476 97.524 740.913 97.524 512 283.087 97.524 512 97.524zm36.571 341.333H475.43V731.43h73.142V438.857zm0-121.905H475.43v73.143h73.142v-73.143z" fill="#0052d9"/></svg>
|
||||
|
After Width: | Height: | Size: 352 B |
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="64" height="64"><path d="M520.665 64.564a29.244 29.244 0 0 0-7.071-.894c-16.211 0-29.35 13.14-29.35 29.35 0 15.83 12.538 28.696 28.223 29.293v.073c.375 0 .751-.014 1.127-.014 216.493 0 389.629 173.942 389.629 390.433 0 216.496-173.136 388.827-389.63 388.827s-389.63-172.333-389.63-388.829c0-.27.01-.536.01-.804h-.01c0-16.209-13.141-29.35-29.35-29.35s-29.35 13.139-29.35 29.35c0 .055.007.11.007.164-.001.214-.007.425-.007.64 0 247.609 200.722 448.331 448.33 448.331 247.607 0 448.33-200.722 448.33-448.33-.002-245.242-196.917-444.456-441.258-448.24z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 653 B |
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M512 97.524c228.913 0 414.476 185.563 414.476 414.476S740.913 926.476 512 926.476 97.524 740.913 97.524 512 283.087 97.524 512 97.524zm193.195 218.331L447.22 581.315 343.284 473.502l-52.663 50.762 156.38 162.23 310.661-319.683-52.467-50.956z" fill="#2ba471"/></svg>
|
||||
|
After Width: | Height: | Size: 376 B |
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M512 97.524c228.913 0 414.476 185.563 414.476 414.476S740.913 926.476 512 926.476 97.524 740.913 97.524 512 283.087 97.524 512 97.524zm36.571 341.333H475.43V731.43h73.142V438.857zm0-121.905H475.43v73.143h73.142v-73.143z" fill="#e37318"/></svg>
|
||||
|
After Width: | Height: | Size: 352 B |
@@ -0,0 +1 @@
|
||||
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path d="M4.162 5.677C2.58 7.258 1.967 9.608 2.874 11.652a32.422 32.422 0 0 0 6.733 9.793 32.423 32.423 0 0 0 9.793 6.733c2.044.907 4.394.293 5.975-1.288l2.543-2.543a1.5 1.5 0 0 0-.073-2.19l-4.808-4.207a1.5 1.5 0 0 0-2.048.068l-2.131 2.131a.736.736 0 0 1-.932.095 26.385 26.385 0 0 1-3.9-3.218 26.385 26.385 0 0 1-3.218-3.9.736.736 0 0 1 .095-.932l2.13-2.13a1.5 1.5 0 0 0 .069-2.05L8.895 3.208a1.5 1.5 0 0 0-2.19-.073L4.162 5.677z" fill="#fff"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h30v30H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 631 B |
@@ -0,0 +1 @@
|
||||
<svg width="26" height="26" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 1a1 1 0 0 1 1-1h24a1 1 0 0 1 1 1v24a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V1zm13 13a4.179 4.179 0 1 0 0-8.357A4.179 4.179 0 0 0 13 14zm-1.857 1.346a5.571 5.571 0 0 0-5.572 5.571v2.25a1 1 0 0 0 1 1H19.43a1 1 0 0 0 1-1v-2.25a5.571 5.571 0 0 0-5.572-5.571L13 18.019l-1.857-2.673zm-9.75-7.31 6.643-6.643h2.232l-8.875 8.875V8.036zm0 12.232v-2.233l6.642-6.641L9.15 12.51l-7.758 7.758zm23.214-5.447v2.233l-2.473 2.473-1.116-1.116 3.59-3.59zm0-10v2.233l-7.092 7.092-1.116-1.116 8.208-8.209zm-4.339-3.428-3.895 3.895-1.117-1.116 2.78-2.78h2.232z" fill="#000" style="fill:#000;fill-opacity:1"/></svg>
|
||||
|
After Width: | Height: | Size: 708 B |
@@ -0,0 +1 @@
|
||||
<svg width="28" height="28" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 2a1 1 0 0 1 1-1h24a1 1 0 0 1 1 1v24a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2zm14.653 14.801a4.18 4.18 0 1 0-3.306 0h-.204a5.571 5.571 0 0 0-5.572 5.572v2.25a1 1 0 0 0 1 1H20.43a1 1 0 0 0 1-1v-2.25a5.571 5.571 0 0 0-5.572-5.572h-.204zm-13.26-9.18L7.62 2.393h2.232l-7.46 7.46V7.621zm0 8.13v-2.232L13.518 2.393h2.233L2.393 15.75zm0 5.898v-2.233l5.459-5.459c.062.626.217 1.224.452 1.78L2.393 21.65zM16.398 7.644a6.14 6.14 0 0 0-1.78-.452l4.798-4.8h2.233l-5.251 5.252zM2.84 24.867l1.731-1.732V25c0 .118.007.234.02.348l-.258.258a1.996 1.996 0 0 1-1.493-.739zM18.549 9.158c.36.393.672.833.923 1.31l6.134-6.135a1.996 1.996 0 0 0-.739-1.493l-6.319 6.318zm.97 6.963.125.071 5.963-5.963V7.997l-5.43 5.43a6.149 6.149 0 0 1-.659 2.694zm2.12 1.741c.346.409.65.854.903 1.33l3.065-3.065v-2.232l-3.967 3.967zm1.79 4.888v1.453l2.178-2.178v-2.233l-2.215 2.215c.024.244.037.492.037.743z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 1005 B |
@@ -0,0 +1 @@
|
||||
<svg width="28" height="28" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="a" fill="#fff"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.952 23.334h8.881a1 1 0 0 0 1-1V11.43L9.952 23.334zM21.364 9.585l1.626-1.958 2.42-1.13a1 1 0 0 1 1.423.907v13.193a1 1 0 0 1-1.423.906l-2.952-1.378-.516-.24a1 1 0 0 1-.578-.907V9.585zm-3.5-4.918L2.367 23.334h-.201a1 1 0 0 1-1-1V5.667a1 1 0 0 1 1-1h15.696zM5.833 11.35h4.082v-1.7H5.833v1.7z"/></mask><path fill-rule="evenodd" clip-rule="evenodd" d="M9.952 23.334h8.881a1 1 0 0 0 1-1V11.43L9.952 23.334zM21.364 9.585l1.626-1.958 2.42-1.13a1 1 0 0 1 1.423.907v13.193a1 1 0 0 1-1.423.906l-2.952-1.378-.516-.24a1 1 0 0 1-.578-.907V9.585zm-3.5-4.918L2.367 23.334h-.201a1 1 0 0 1-1-1V5.667a1 1 0 0 1 1-1h15.696zM5.833 11.35h4.082v-1.7H5.833v1.7z" fill="#fff" style="fill:#fff;fill-opacity:1"/><path d="m9.952 23.334-1.308-1.086-2.313 2.786h3.62v-1.7zm9.881-11.904h1.7V6.72l-3.008 3.624 1.308 1.086zm3.157-3.803-.72-1.54-.345.161-.244.294 1.309 1.085zm-1.626 1.958L20.056 8.5l-.392.472v.614h1.7zm4.046-3.087.72 1.54-.72-1.54zm1.423.906h1.7-1.7zm0 13.193h-1.7 1.7zm-1.423.906-.719 1.54.72-1.54zm-2.952-1.378.72-1.54-.72 1.54zm-.516-.24-.72 1.54.72-1.54zm-.578-.907h-1.7 1.7zM2.368 23.334v1.7h.798l.51-.614-1.308-1.086zM17.863 4.667l1.308 1.086 2.313-2.786h-3.62v1.7zM9.916 11.35v1.7h1.7v-1.7h-1.7zm-4.083 0h-1.7v1.7h1.7v-1.7zm4.083-1.7h1.7v-1.7h-1.7v1.7zm-4.083 0v-1.7h-1.7v1.7h1.7zm13 11.984H9.952v3.4h8.881v-3.4zm-.7.7a.7.7 0 0 1 .7-.7v3.4a2.7 2.7 0 0 0 2.7-2.7h-3.4zm0-10.904v10.904h3.4V11.43h-3.4zm.392-1.086L8.644 22.248l2.616 2.171 9.881-11.903-2.616-2.172zm3.157-3.802-1.626 1.957 2.616 2.172 1.626-1.958-2.616-2.171zm3.01-1.585-2.421 1.13 1.438 3.08 2.42-1.129-1.438-3.08zm3.841 2.447c0-1.976-2.052-3.282-3.842-2.447l1.438 3.081a.7.7 0 0 1-.996-.634h3.4zm0 13.193V7.404h-3.4v13.193h3.4zm-3.842 2.447c1.79.835 3.842-.472 3.842-2.447h-3.4a.7.7 0 0 1 .996-.635l-1.438 3.082zm-2.952-1.378 2.952 1.378 1.438-3.082-2.952-1.377-1.438 3.08zm-.516-.241.516.24 1.438-3.08-.517-.241-1.437 3.08zm-1.559-2.447a2.7 2.7 0 0 0 1.559 2.447l1.438-3.081a.7.7 0 0 1 .403.634h-3.4zm0-9.393v9.393h3.4V9.585h-3.4zM3.676 24.42 19.171 5.753 16.555 3.58 1.06 22.248l2.616 2.171zm-1.308-2.785h-.201v3.4h.201v-3.4zm-.201 0a.7.7 0 0 1 .7.7h-3.4a2.7 2.7 0 0 0 2.7 2.7v-3.4zm.7.7V5.667h-3.4v16.667h3.4zm0-16.667a.7.7 0 0 1-.7.7v-3.4a2.7 2.7 0 0 0-2.7 2.7h3.4zm-.7.7h15.696v-3.4H2.166v3.4zm7.75 3.283H5.832v3.4h4.083v-3.4zm-1.7 0v1.7h3.4v-1.7h-3.4zm-2.384 1.7h4.083v-3.4H5.833v3.4zm1.7 0v-1.7h-3.4v1.7h3.4z" fill="#fff" style="fill:#fff;fill-opacity:1" mask="url(#a)"/><path d="M4.563 25.269 22.14 4.084" stroke="#fff" style="stroke:#fff;stroke-opacity:1" stroke-width="2" stroke-linecap="square" stroke-linejoin="round"/></svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="26" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.916 8.2h.85V4.8H3.984v3.4h4.933zm-7.9-6.533a.15.15 0 0 1 .15-.15h16.667a.15.15 0 0 1 .15.15v16.666a.15.15 0 0 1-.15.15H1.167a.15.15 0 0 1-.15-.15V1.667zm20.198 3.355a.15.15 0 0 1 .087-.136l3.469-1.618a.15.15 0 0 1 .213.135v13.193a.15.15 0 0 1-.213.136l-3.47-1.618a.15.15 0 0 1-.086-.136V5.022z" fill="#22262E" stroke="#22262E" stroke-width="1.7" stroke-linecap="round"/></svg>
|
||||
|
After Width: | Height: | Size: 463 B |
|
After Width: | Height: | Size: 221 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.66683 9.33337H3.3335V4.00004C3.3335 3.63185 3.63197 3.33337 4.00016 3.33337L9.3335 3.33337V4.66671H5.60963L9.8049 8.86199L8.86209 9.8048L4.66683 5.60952V9.33337ZM15.3333 10.6667H16.6667V16C16.6667 16.3682 16.3682 16.6667 16 16.6667L10.6667 16.6667L10.6667 15.3333H14.3905L10.1953 11.138L11.1381 10.1952L15.3333 14.3905V10.6667Z" fill="white"/>
|
||||
<path d="M0.666667 1.33333C0.666667 0.965144 0.965144 0.666667 1.33333 0.666667H18.6667C19.0349 0.666667 19.3333 0.965144 19.3333 1.33333V18.6667C19.3333 19.0349 19.0349 19.3333 18.6667 19.3333H1.33333C0.965143 19.3333 0.666667 19.0349 0.666667 18.6667V1.33333Z" stroke="white" stroke-width="1.33333"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 801 B |
@@ -0,0 +1 @@
|
||||
<svg t="1708400849531" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8267" width="200" height="200"><path d="M121.51 460.15h779.64v100.6H121.51z" p-id="8268" fill="#ffffff"></path><path d="M461.035 900.271v-779.64h100.6v779.64z" p-id="8269" fill="#ffffff"></path></svg>
|
||||
|
After Width: | Height: | Size: 315 B |
@@ -0,0 +1,6 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.769231" y="0.769231" width="18.4615" height="18.4615" rx="0.769231" stroke="white" stroke-width="1.53846"/>
|
||||
<path d="M11.5385 12.3077C11.5385 11.8829 11.8829 11.5385 12.3077 11.5385H19.2308V18.4615C19.2308 18.8864 18.8864 19.2308 18.4616 19.2308H11.5385V12.3077Z" stroke="white" stroke-width="1.53846"/>
|
||||
<path d="M0.769287 0.769226L8.9723 8.92412" stroke="white" stroke-width="1.53846"/>
|
||||
<path d="M9.4967 4.71716V9.4486H4.74146" stroke="white" stroke-width="1.53846" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@@ -0,0 +1 @@
|
||||
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M30 16.05c0-2.235-1.228-4.33-3.314-5.135A32.423 32.423 0 0 0 15 8.751c-4.12 0-8.06.766-11.685 2.164C1.228 11.719 0 13.815 0 16.051v3.597a1.5 1.5 0 0 0 1.6 1.496l6.375-.425a1.5 1.5 0 0 0 1.4-1.496v-3.014c0-.353.245-.659.591-.726A26.382 26.382 0 0 1 15 15.001c1.722 0 3.404.166 5.034.482a.736.736 0 0 1 .591.726v3.014a1.5 1.5 0 0 0 1.4 1.496l6.375.425a1.5 1.5 0 0 0 1.6-1.496V16.05z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 485 B |
@@ -0,0 +1 @@
|
||||
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.75 7.5a6.25 6.25 0 0 1 11.133-3.902L8.873 16.862a6.28 6.28 0 0 1-.123-1.237V7.5zM6.806 19.352A8.967 8.967 0 0 1 6 15.625V13.75H4v1.875c0 1.963.514 3.806 1.416 5.402l1.39-1.675zm2.406 5.629 1.292-1.558A9 9 0 0 0 24 15.625v-1.874h2v1.875c0 5.738-4.393 10.45-10 10.955V30h-2v-3.42a10.934 10.934 0 0 1-4.788-1.6zm3.086-3.719 8.952-10.784v5.147a6.25 6.25 0 0 1-8.952 5.637z" fill="#fff" style="fill:#fff;fill-opacity:1"/><path d="M6.419 24.084 22.094 5.209" stroke="#fff" style="stroke:#fff;stroke-opacity:1" stroke-width="2" stroke-linecap="square" stroke-linejoin="round"/></svg>
|
||||
|
After Width: | Height: | Size: 703 B |
@@ -0,0 +1 @@
|
||||
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 15.625V13.75h2v1.875a9 9 0 1 0 18 0V13.75h2v1.875c0 5.738-4.393 10.45-10 10.955V30h-2v-3.42c-5.607-.505-10-5.217-10-10.955z" fill="#22262E"/><rect x="8.75" y="1.25" width="12.5" height="20.625" rx="6.25" fill="#22262E"/></svg>
|
||||
|
After Width: | Height: | Size: 353 B |
@@ -0,0 +1 @@
|
||||
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"><circle opacity=".5" cx="15" cy="15" r="15" fill="#22262E"/><path fill-rule="evenodd" clip-rule="evenodd" d="M9.484 14.313a.4.4 0 0 1 .014-.565l.87-.827a.4.4 0 0 1 .566.015L15 17.216l4.066-4.28a.4.4 0 0 1 .565-.015l.87.827a.4.4 0 0 1 .015.565l-5.033 5.298a.667.667 0 0 1-.966 0l-5.033-5.298z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 387 B |
@@ -0,0 +1 @@
|
||||
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><g filter="url(#a)"><mask id="b" fill="#fff"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.5 11.05a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9zm-2 1.45a6 6 0 0 0-6 6V21a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-2.5a6 6 0 0 0-6-6l-2 2.88-2-2.88z"/></mask><path d="m8.5 12.5 1.396-.97-.507-.73H8.5v1.7zm4 0v-1.7h-.889l-.507.73 1.396.97zm-2 2.88-1.396.969 1.396 2.01 1.396-2.01-1.396-.97zm2.8-8.83a2.8 2.8 0 0 1-2.8 2.8v3.4a6.2 6.2 0 0 0 6.2-6.2h-3.4zm-2.8-2.8a2.8 2.8 0 0 1 2.8 2.8h3.4a6.2 6.2 0 0 0-6.2-6.2v3.4zm-2.8 2.8a2.8 2.8 0 0 1 2.8-2.8V.35a6.2 6.2 0 0 0-6.2 6.2h3.4zm2.8 2.8a2.8 2.8 0 0 1-2.8-2.8H4.3a6.2 6.2 0 0 0 6.2 6.2v-3.4zM4.2 18.5a4.3 4.3 0 0 1 4.3-4.3v-3.4a7.7 7.7 0 0 0-7.7 7.7h3.4zm0 2.5v-2.5H.8V21h3.4zm-.7-.7a.7.7 0 0 1 .7.7H.8a2.7 2.7 0 0 0 2.7 2.7v-3.4zm14 0h-14v3.4h14v-3.4zm-.7.7a.7.7 0 0 1 .7-.7v3.4a2.7 2.7 0 0 0 2.7-2.7h-3.4zm0-2.5V21h3.4v-2.5h-3.4zm-4.3-4.3a4.3 4.3 0 0 1 4.3 4.3h3.4a7.7 7.7 0 0 0-7.7-7.7v3.4zm-.604 2.149 2-2.879-2.792-1.94-2 2.88 2.792 1.939zM7.104 13.47l2 2.879 2.792-1.94-2-2.879-2.792 1.94z" fill="#D5E0F2" mask="url(#b)"/></g><path d="M16 11h7m-3.5-3.5v7" stroke="#D5E0F2" stroke-width="1.7"/><defs><filter id="a" x="-5.5" y="-5.949" width="32" height="35.95" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feGaussianBlur in="BackgroundImageFix" stdDeviation="4"/><feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_2584_236"/><feBlend in="SourceGraphic" in2="effect1_backgroundBlur_2584_236" result="shape"/></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.5 4H3a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-5.5" stroke="#D5E0F2" stroke-width="1.5"/><path fill-rule="evenodd" clip-rule="evenodd" d="M11.5 3.5v5h5v-5h-5zM11 2a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1h-6z" fill="#D5E0F2"/></svg>
|
||||
|
After Width: | Height: | Size: 348 B |
@@ -0,0 +1 @@
|
||||
<svg width="28" height="28" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M25.018 5.763a2 2 0 0 1 2 2v15.528a2 2 0 0 1-2 2H2.982a2 2 0 0 1-2-2V7.763a2 2 0 0 1 2-2h4.262a2 2 0 0 0 1.494-.67l1.41-1.587a2 2 0 0 1 1.495-.672h4.714a2 2 0 0 1 1.494.671l1.41 1.587a2 2 0 0 0 1.495.671h4.262zM11.723 9.585a5.907 5.907 0 0 1 2.186-.417c1.719 0 3.27.733 4.341 1.903V9.918h1.5v5.001h-1.5v-.005c-.002-2.332-1.932-4.245-4.34-4.245-.58 0-1.13.11-1.633.31l-.554-1.394zM8.25 19.919v-5h1.5c0 2.334 1.93 4.25 4.34 4.25.58 0 1.13-.111 1.633-.31l.554 1.393a5.908 5.908 0 0 1-2.186.417 5.873 5.873 0 0 1-4.341-1.903v1.153h-1.5z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 677 B |
@@ -0,0 +1 @@
|
||||
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"><circle opacity=".5" cx="15" cy="15" r="15" fill="#22262E" style="fill:color(display-p3 .1333 .149 .1804);fill-opacity:1"/><path fill-rule="evenodd" clip-rule="evenodd" d="M20.516 17.452a.4.4 0 0 1-.014.565l-.87.827a.4.4 0 0 1-.566-.015L15 14.55l-4.066 4.28a.4.4 0 0 1-.566.015l-.87-.827a.4.4 0 0 1-.014-.565l5.033-5.298a.667.667 0 0 1 .966 0l5.033 5.298z" fill="#fff" style="fill:#fff;fill-opacity:1"/></svg>
|
||||
|
After Width: | Height: | Size: 484 B |
@@ -0,0 +1 @@
|
||||
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="m10.36 22.842 4.235 3.56c.697.587 1.76.091 1.76-.82V15.62l-5.995 7.223zm13.356-16.09 1.285-1.548A13.955 13.955 0 0 1 29 15c0 5.183-2.817 9.707-7 12.127l-.865.5-1.001-1.731.865-.5C24.59 23.318 27 19.44 27 15c0-3.194-1.248-6.097-3.284-8.248zm-3.278 3.95 1.288-1.553C23.14 10.613 24 12.71 24 15c0 2.869-1.35 5.433-3.445 6.832l-.831.555-1.11-1.663.83-.556C20.938 19.172 22 17.258 22 15c0-1.716-.613-3.232-1.562-4.299zm-4.082-4.22L3.928 21.456H2.252c-.592 0-1.072-.48-1.072-1.072V9.635c0-.591.478-1.07 1.069-1.072l6.073-.017c.251 0 .494-.09.687-.251l5.586-4.697c.697-.586 1.76-.091 1.76.82v2.065z" fill="#fff"/><path d="M4.564 25.268 22.14 4.084" stroke="#fff" stroke-width="2" stroke-linecap="square" stroke-linejoin="round"/></svg>
|
||||
|
After Width: | Height: | Size: 852 B |
@@ -0,0 +1 @@
|
||||
<svg width="28" height="26" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="m20.135.373.866.5C25.183 3.294 28 7.818 28 13c0 5.183-2.817 9.707-7 12.127l-.865.5-1.001-1.731.865-.5C23.59 21.318 26 17.44 26 13s-2.411-8.319-6-10.395l-.866-.5L20.135.372zm-6.49 1.016a1.071 1.071 0 0 1 1.71.86V23.75c0 .881-1.003 1.386-1.71.86l-6.65-4.945a1.071 1.071 0 0 0-.639-.211H1.252c-.592 0-1.072-.48-1.072-1.072V7.634c0-.59.478-1.07 1.068-1.071l5.11-.017c.23 0 .452-.075.636-.211l6.65-4.946zm5.91 4.78-.831-.556-1.111 1.663.832.556C19.937 8.828 21 10.742 21 13c0 2.259-1.063 4.172-2.555 5.168l-.832.556 1.11 1.663.832-.555C21.65 18.432 23 15.869 23 13c0-2.869-1.35-5.433-3.445-6.832z" fill="#2E333D"/></svg>
|
||||
|
After Width: | Height: | Size: 739 B |
@@ -0,0 +1 @@
|
||||
<svg width="20" height="19" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.302 2.09a7.164 7.164 0 0 0-8.287 7.539l-1.978.358A9.274 9.274 0 0 1 0 9.162C0 4.102 4.104 0 9.167 0c.508 0 1.007.041 1.493.12l-.358 1.97zm-.239 1.322A5.832 5.832 0 0 0 3.338 9.4l1.998-.364a3.832 3.832 0 0 1 4.37-3.655l.357-1.97zM8.181 7.218l10.445-.005a.47.47 0 0 1 .457.57l-2.287 10.186a.467.467 0 0 1-.823.19l-2.32-2.896C9.61 18.498 3.71 17.846.473 13.806c-.138-.172.049-.408.259-.339a8.44 8.44 0 0 0 7.94-1.42l1.463-1.172-2.32-2.896a.468.468 0 0 1 .365-.761z" fill="#fff" style="fill:#fff;fill-opacity:1"/></svg>
|
||||
|
After Width: | Height: | Size: 643 B |
@@ -0,0 +1 @@
|
||||
<svg width="10" height="6" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.5 0 5 3.75.5 0v1.562l4.116 3.43.384.32.384-.32L9.5 1.562V0z" fill="#666"/></svg>
|
||||
|
After Width: | Height: | Size: 206 B |
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1.536 6.682c-.33-.955.088-1.98.9-2.581.617-.456 1.236-.916 1.589-1.178a.396.396 0 0 1 .539.062l1.925 2.264a.396.396 0 0 1 0 .513l-1.18 1.39a.388.388 0 0 0-.041.45 8.667 8.667 0 0 0 1.37 1.758c.57.57 1.12.982 1.765 1.364a.389.389 0 0 0 .45-.041l1.383-1.174a.397.397 0 0 1 .514 0l2.266 1.925c.159.135.186.37.062.538l-1.185 1.604c-.596.806-1.614 1.216-2.562.89a12.545 12.545 0 0 1-4.797-3.003 12.54 12.54 0 0 1-2.998-4.78z" fill="#1C66E5"/><path fill-rule="evenodd" clip-rule="evenodd" d="M8.889 2.133a.356.356 0 0 0-.356.356v3.685c0 .196.16.355.356.355h3.685c.196 0 .355-.159.355-.355v-.186a.32.32 0 0 1 .455-.29l.687.32a.356.356 0 0 0 .506-.322v-2.73c0-.26-.27-.432-.506-.322l-.687.32a.32.32 0 0 1-.455-.29V2.49a.356.356 0 0 0-.355-.356H8.889z" fill="#1C66E5"/></svg>
|
||||
|
After Width: | Height: | Size: 851 B |
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="10" height="10"><path d="M512 466.752 86.656 41.344a32 32 0 0 0-45.312 45.312L466.752 512 41.344 937.344a32 32 0 0 0 45.312 45.312L512 557.248l425.344 425.408a32 32 0 0 0 45.312-45.312L557.248 512 982.656 86.656a32 32 0 0 0-45.312-45.312L512 466.752z" fill="#707070"/></svg>
|
||||
|
After Width: | Height: | Size: 358 B |
@@ -0,0 +1 @@
|
||||
<svg width="100" height="100" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="url(#a)" d="M-5-5h110v110H-5z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M25 71.5c0-10.264 7.93-18.676 17.998-19.443.496-.038.997-.057 1.502-.057h13c.505 0 1.006.02 1.501.057C69.07 52.824 77 61.236 77 71.5v6.783H25V71.5zM44.5 45.605a14.075 14.075 0 0 1-.205-.104c-4.704-2.431-7.92-7.34-7.92-13.001 0-8.077 6.548-14.625 14.625-14.625S65.625 24.423 65.625 32.5c0 5.66-3.216 10.57-7.92 13-.068.036-.136.07-.205.105a14.565 14.565 0 0 1-6.5 1.52c-2.335 0-4.542-.547-6.5-1.52z" fill="#D5E0F2"/><defs><linearGradient id="a" x1="73.5" y1="-5" x2="5" y2="98.5" gradientUnits="userSpaceOnUse"><stop stop-color="#7C859B"/><stop offset="1" stop-color="#747C90"/></linearGradient></defs></svg>
|
||||
|
After Width: | Height: | Size: 777 B |
@@ -0,0 +1 @@
|
||||
<svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"><path d="M512 170.667V256a256 256 0 1 1-223.573 131.2l-74.496-41.6A341.333 341.333 0 1 0 512 170.667z" opacity=".3"/></svg>
|
||||
|
After Width: | Height: | Size: 225 B |
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16" class="design-iconfont"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.828 12.476c.754.429 1.61.722 2.505.82V15c0 .184.15.334.334.334h.666c.184 0 .334-.15.334-.334v-1.703C11.54 12.98 14 10.666 14 8.273v-.592a.333.333 0 0 0-.333-.333H13a.333.333 0 0 0-.333.333v.592l-.004.12c-.095 1.76-2.265 3.605-4.659 3.607h-.008c-.77 0-1.519-.192-2.181-.51l-.987.986zm2.004-2.004c.364.12.758.186 1.168.186 1.827 0 3.333-1.303 3.333-2.932V5.97l-4.501 4.502zm4.075-8.317-6.17 6.17a2.602 2.602 0 0 1-.067-.468l-.003-.131V3.59C4.667 1.961 6.173.658 8 .658c1.24 0 2.333.601 2.907 1.497zM3.625 9.437l-.979.978c-.384-.625-.615-1.307-.643-1.999L2 8.273v-.608c0-.182.147-.33.33-.333l.664-.007a.333.333 0 0 1 .336.332l.003.616c0 .389.104.784.292 1.164z" fill="#fff"/><rect x=".61" y="13.451" width="19.013" height="1.5" rx=".75" transform="rotate(-45 .61 13.451)" fill="#FE3C44"/></svg>
|
||||
|
After Width: | Height: | Size: 939 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18.4437 12.449C18.4437 14.1142 18.2336 15.3515 21.5089 15.7126C24.7875 16.0737 24.3666 13.6794 24.3662 12.0669C24.3649 10.2061 20.0602 7.61895 13.2726 7.6173C6.48662 7.61735 2.1789 10.205 2.17888 12.067C2.17887 13.68 1.75621 16.0726 5.03315 15.7123C8.31009 15.3537 8.10005 14.1155 8.09837 12.4495C8.10134 11.2862 10.7587 11.0316 13.2725 11.0298C15.7863 11.0281 18.4454 11.2844 18.4437 12.449Z" fill="#FE3C44"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 536 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.33337 9.33331H0.333374V0.99998C0.333374 0.63179 0.631851 0.333313 1.00004 0.333313L9.33338 0.333313V2.33331H3.74758L10.0405 8.62624L8.62627 10.0404L2.33337 3.74753V9.33331ZM18.3331 11.3333H20.3331V19.6666C20.3331 20.0348 20.0347 20.3333 19.6665 20.3333L11.3331 20.3333L11.3331 18.3333H16.9189L10.626 12.0403L12.0402 10.6261L18.3331 16.919V11.3333Z" fill="#101419"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 520 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.66666 4.16668C6.66666 2.32834 8.16166 0.833344 9.99999 0.833344C11.8383 0.833344 13.3333 2.32834 13.3333 4.16668V9.16668C13.3333 11.005 11.8383 12.5 9.99999 12.5C8.16166 12.5 6.66666 11.005 6.66666 9.16668V4.16668ZM6.66666 18.3333C6.66666 17.8725 7.03999 17.5 7.49999 17.5H12.5C12.9608 17.5 13.3333 17.8725 13.3333 18.3333C13.3333 18.7942 12.9608 19.1667 12.5 19.1667H7.49999C7.03999 19.1667 6.66666 18.7942 6.66666 18.3333Z" fill="#101419"/>
|
||||
<path d="M15.8333 8.3512V9.50825C15.8333 12.081 13.2217 15 9.99999 15C6.77833 15 4.16666 12.081 4.16666 9.50825V8.33334" stroke="#101419" stroke-width="1.66667" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 783 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="15" height="21" viewBox="0 0 15 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.6247 0.719168C14.1934 0.374158 13.5641 0.44408 13.2191 0.875342L10.8168 3.83203C10.1789 3.02455 9.15387 2.50004 8.00001 2.50004C6.06976 2.50004 4.50001 3.96785 4.50001 5.77276V10.6819C4.50001 10.9563 4.5363 11.2229 4.60463 11.4778L3.388 12.9752C2.98449 12.3433 2.75001 11.6522 2.75001 10.9717V9.81819L2.74319 9.71556C2.6892 9.31213 2.32108 9.00001 1.87501 9.00001C1.39176 9.00001 1.00001 9.36632 1.00001 9.81819V10.9717L1.00466 11.1761C1.05557 12.2968 1.52161 13.4016 2.26939 14.3519L0.219137 16.8753L0.146861 16.9782C-0.112977 17.4017 -0.0227767 17.9624 0.375311 18.2809C0.806573 18.6259 1.43587 18.556 1.78088 18.1247L3.71661 15.7423C3.71849 15.7437 3.72038 15.745 3.72227 15.7464L4.2997 15.0246L8.28088 10.1247L14.7809 2.12473L14.8532 2.02191C15.113 1.59834 15.0228 1.03764 14.6247 0.719168ZM7.72499 13.9446L11.5 9.22582V10.6819C11.5 12.4868 9.93026 13.9546 8.00001 13.9546C7.90746 13.9546 7.81575 13.9512 7.72499 13.9446ZM6.60445 15.3453L5.50798 16.7159C6.29225 17.0136 7.13532 17.1818 8.00001 17.1818C11.6976 17.1818 15 14.1064 15 10.9717V9.83572L14.9932 9.73309C14.9392 9.32966 14.5711 9.01754 14.125 9.01754C13.6418 9.01754 13.25 9.38385 13.25 9.83572V10.9717L13.2445 11.1527C13.1138 13.3262 10.6589 15.5455 8.00001 15.5455C7.52424 15.5455 7.05501 15.4744 6.60445 15.3453ZM5.37501 18.8637C4.89201 18.8637 4.50001 19.2294 4.50001 19.6819C4.50001 20.1343 4.89201 20.5 5.37501 20.5H10.625C11.1089 20.5 11.5 20.1343 11.5 19.6819C11.5 19.2294 11.1089 18.8637 10.625 18.8637H5.37501Z" fill="#101419"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.672 5.777a.6.6 0 0 0-.331.536v2.693a.6.6 0 0 0 .33.536l2.803 1.406a.2.2 0 0 0 .29-.179V4.55a.2.2 0 0 0-.29-.178l-2.802 1.406z" fill="#ADADAD"/><g filter="url(#a)"><rect x=".667" y="2.553" width="10.667" height="10.213" rx="1.5" fill="#ADADAD"/></g><defs><filter id="a" x="-7.333" y="-5.447" width="26.667" height="26.213" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feGaussianBlur in="BackgroundImageFix" stdDeviation="4"/><feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_131_1449"/><feBlend in="SourceGraphic" in2="effect1_backgroundBlur_131_1449" result="shape"/></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 819 B |
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.672 6.117a.6.6 0 0 0-.331.536v2.693a.6.6 0 0 0 .33.537l2.803 1.405a.2.2 0 0 0 .29-.178V4.89a.2.2 0 0 0-.29-.179l-2.802 1.406z" fill="#12B969"/><g filter="url(#a)"><rect x=".667" y="2.894" width="10.667" height="10.213" rx="1.5" fill="#12B969"/></g><defs><filter id="a" x="-7.333" y="-5.106" width="26.667" height="26.213" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feGaussianBlur in="BackgroundImageFix" stdDeviation="4"/><feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_1977_11630"/><feBlend in="SourceGraphic" in2="effect1_backgroundBlur_1977_11630" result="shape"/></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 823 B |
@@ -0,0 +1 @@
|
||||
<svg width="28" height="28" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M.761 9.332C.001 7.134.963 4.773 2.833 3.39 4.252 2.343 5.676 1.285 6.49.681a.912.912 0 0 1 1.24.141l4.429 5.21c.29.34.29.841 0 1.182l-2.716 3.198a.893.893 0 0 0-.093 1.034 19.946 19.946 0 0 0 3.151 4.048 19.62 19.62 0 0 0 4.064 3.137.895.895 0 0 0 1.033-.094l3.186-2.702a.913.913 0 0 1 1.181 0l5.214 4.431c.366.311.429.852.143 1.238l-2.727 3.69c-1.372 1.855-3.714 2.798-5.895 2.047a28.865 28.865 0 0 1-11.04-6.908A28.855 28.855 0 0 1 .761 9.332z" fill="#12B969"/></svg>
|
||||
|
After Width: | Height: | Size: 554 B |
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.917 7.57v-.731h1.5v.73a4.583 4.583 0 1 0 9.166 0v-.73h1.5v.73a6.084 6.084 0 0 1-5.333 6.038v1.302h-1.5v-1.302a6.084 6.084 0 0 1-5.333-6.038z" fill="#ADADAD"/><rect x="4.667" y="1.091" width="6.667" height="9.897" rx="3.333" fill="#ADADAD"/></svg>
|
||||
|
After Width: | Height: | Size: 373 B |
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.917 7.57v-.731h1.5v.73a4.583 4.583 0 1 0 9.166 0v-.73h1.5v.73a6.084 6.084 0 0 1-5.333 6.038v1.302h-1.5v-1.302a6.084 6.084 0 0 1-5.333-6.038z" fill="#12B969"/><rect x="4.667" y="1.091" width="6.667" height="9.897" rx="3.333" fill="#12B969"/></svg>
|
||||
|
After Width: | Height: | Size: 373 B |
@@ -0,0 +1,11 @@
|
||||
import MacPermitZhPng from './mac/permit-zh.jpg';
|
||||
import MacPermitEnPng from './mac/permit-en.jpg';
|
||||
import WinPermitZhPng from './win/permit-zh.png';
|
||||
import WinPermitEnPng from './win/permit-en.png';
|
||||
|
||||
export {
|
||||
MacPermitZhPng,
|
||||
MacPermitEnPng,
|
||||
WinPermitZhPng,
|
||||
WinPermitEnPng,
|
||||
};
|
||||
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="28" height="28" fill="none" xmlns="http://www.w3.org/2000/svg"><g filter="url(#a)"><circle cx="14" cy="14" r="12" fill="#fff"/></g><path fill-rule="evenodd" clip-rule="evenodd" d="M10.667 10a3.333 3.333 0 0 1 5.937-2.08l-5.872 7.073a3.345 3.345 0 0 1-.065-.66V10zM9.63 16.321a4.782 4.782 0 0 1-.43-1.988v-1H8.133v1c0 1.047.275 2.03.755 2.881l.742-.893zm1.283 3.002.69-.83a4.8 4.8 0 0 0 7.198-4.16v-1h1.066v1a5.867 5.867 0 0 1-5.334 5.843V22h-1.066v-1.824a5.831 5.831 0 0 1-2.554-.853zm1.646-1.983 4.774-5.751v2.744a3.333 3.333 0 0 1-4.774 3.007z" fill="#E6395C"/><path d="m9.423 18.845 8.36-10.067" stroke="#E6395C" stroke-width="1.067" stroke-linecap="square" stroke-linejoin="round"/><defs><filter id="a" x="0" y="0" width="28" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset/><feGaussianBlur stdDeviation="1"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_1741_10678"/><feBlend in="SourceGraphic" in2="effect1_dropShadow_1741_10678" result="shape"/></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="28" height="28" fill="none" xmlns="http://www.w3.org/2000/svg"><g filter="url(#a)"><circle cx="14" cy="14" r="12" fill="#fff"/></g><path fill-rule="evenodd" clip-rule="evenodd" d="M15.812 22.538c4.716-4.715 4.716-12.36 0-17.076l-1.767 1.767a9.575 9.575 0 0 1 0 13.541l1.767 1.768z" fill="#1C66E5"/><path fill-rule="evenodd" clip-rule="evenodd" d="M12.188 19.136a7.264 7.264 0 0 0 0-10.273l-1.768 1.768a4.764 4.764 0 0 1 0 6.737l1.768 1.768zM9.121 16.07a2.927 2.927 0 0 0 0-4.14l-2.018 2.018a.073.073 0 0 1 0 .103l2.018 2.018z" fill="#1C66E5"/><defs><filter id="a" x="0" y="0" width="28" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset/><feGaussianBlur stdDeviation="1"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_124_647"/><feBlend in="SourceGraphic" in2="effect1_dropShadow_124_647" result="shape"/></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="28" height="28" fill="none" xmlns="http://www.w3.org/2000/svg"><g filter="url(#a)"><circle cx="14" cy="14" r="12" fill="#fff"/></g><path fill-rule="evenodd" clip-rule="evenodd" d="M10.667 10a3.333 3.333 0 0 1 5.937-2.08l-5.872 7.073a3.345 3.345 0 0 1-.065-.66V10zM9.63 16.321a4.782 4.782 0 0 1-.43-1.988v-1H8.133v1c0 1.047.275 2.03.755 2.881l.742-.893zm1.283 3.002.69-.83a4.8 4.8 0 0 0 7.198-4.16v-1h1.066v1a5.867 5.867 0 0 1-5.334 5.843V22h-1.066v-1.824a5.831 5.831 0 0 1-2.554-.853zm1.646-1.983 4.774-5.751v2.744a3.333 3.333 0 0 1-4.774 3.007z" fill="#E6395C"/><path d="m9.423 18.845 8.36-10.067" stroke="#E6395C" stroke-width="1.067" stroke-linecap="square" stroke-linejoin="round"/><defs><filter id="a" x="0" y="0" width="28" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset/><feGaussianBlur stdDeviation="1"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_1741_10678"/><feBlend in="SourceGraphic" in2="effect1_dropShadow_1741_10678" result="shape"/></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"><g opacity=".8"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.833 5A4.167 4.167 0 0 1 13.7 3.083l-7.503 9.039a4.152 4.152 0 0 1-.364-1.705V5zm-.772 8.49a5.79 5.79 0 0 1-.878-3.073v-1.25h-1.7v1.25c0 1.659.538 3.192 1.448 4.435l1.13-1.361zm2.011 3.852 1.15-1.385a5.817 5.817 0 0 0 7.595-5.54v-1.25h1.7v1.25a7.518 7.518 0 0 1-6.684 7.47V20H9.167v-2.112a7.468 7.468 0 0 1-2.095-.546zm2.326-2.802 4.769-5.745v1.622a4.167 4.167 0 0 1-4.77 4.123z" fill="#D5E0F2"/><path d="M5.041 16.654 15.325 4.27" stroke="#D5E0F2" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></g></svg>
|
||||
|
After Width: | Height: | Size: 668 B |
@@ -0,0 +1 @@
|
||||
<svg width="28" height="28" fill="none" xmlns="http://www.w3.org/2000/svg"><g filter="url(#a)"><circle cx="14" cy="14" r="12" fill="#fff"/></g><path fill-rule="evenodd" clip-rule="evenodd" d="M15.812 22.538c4.716-4.715 4.716-12.36 0-17.076l-1.767 1.767a9.575 9.575 0 0 1 0 13.541l1.767 1.768z" fill="#1C66E5"/><path fill-rule="evenodd" clip-rule="evenodd" d="M12.188 19.136a7.264 7.264 0 0 0 0-10.273l-1.768 1.768a4.764 4.764 0 0 1 0 6.737l1.768 1.768zM9.121 16.07a2.927 2.927 0 0 0 0-4.14l-2.018 2.018a.073.073 0 0 1 0 .103l2.018 2.018z" fill="#1C66E5"/><defs><filter id="a" x="0" y="0" width="28" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset/><feGaussianBlur stdDeviation="1"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/><feBlend in2="BackgroundImageFix" result="effect1_dropShadow_124_647"/><feBlend in="SourceGraphic" in2="effect1_dropShadow_124_647" result="shape"/></filter></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<Overlay
|
||||
bgColor="#22262ed9"
|
||||
:bgImage="defaultAvatarSrc"
|
||||
:customStyle="{ position: 'absolute', zIndex: 0 }"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
virtualHost: true
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Overlay from '../../base/Overlay/Overlay.vue';
|
||||
import defaultAvatarSrc from '../../../assets/common/defaultAvatar.svg';
|
||||
</script>
|
||||
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div class="groupcall-container">
|
||||
<TopBar />
|
||||
<Waiting v-if="callStatus === CallStatus.CALLING && callRole === CallRole.CALLEE && !isFloatWindow" />
|
||||
<MediaContainer />
|
||||
<Tip />
|
||||
<ButtonPanel />
|
||||
<BackGround />
|
||||
<SelectUser
|
||||
v-if="showSelectUser"
|
||||
:isNeedSearch="true"
|
||||
:userList="groupMemberList"
|
||||
:isPC="TUIGlobal.isPC"
|
||||
:total="memberCount"
|
||||
@confirm="handleSelectedResult"
|
||||
@cancel="handleCancel"
|
||||
@getMore="getMoreMemberList"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, provide, toRefs, onMounted, onUnmounted } from '../../../adapter-vue';
|
||||
import TopBar from '../common/TopBar/TopBar.vue';
|
||||
import Waiting from '../common/Waiting/Waiting.vue';
|
||||
import MediaContainer from './MediaContainer/MediaContainer.vue';
|
||||
import Tip from '../common/Tip/Tip.vue';
|
||||
import ButtonPanel from '../common/ButtonPanel/ButtonPanel.vue';
|
||||
import SelectUser from '../common/SelectUser/SelectUser.vue';
|
||||
import BackGround from './BackGround/BackGround.vue';
|
||||
import { ButtonPanelContextKey, FocusContextKey } from '../../context';
|
||||
import { useCallInfoContext, useFloatWindowContext, useUserInfoExcludeVolumeContext } from '../../hooks';
|
||||
import { CallRole, CallStatus, TUIGlobal, TUIStore, TUICallKitAPI, StoreName, NAME } from '../../../TUICallService';
|
||||
|
||||
const focusElement = ref(null);
|
||||
const buttonPanelStatus = ref('open');
|
||||
const showSelectUser = ref(false);
|
||||
const memberCount = ref(0);
|
||||
const groupMemberList = ref([]);
|
||||
const backupGroupMemberList = ref([]);
|
||||
const offset = ref(0);
|
||||
const count: number = 30;
|
||||
|
||||
const FocusContextValue = focusElement;
|
||||
const ButtonPanelContextValue = { status: buttonPanelStatus };
|
||||
|
||||
|
||||
const { callRole, callStatus } = toRefs(useCallInfoContext());
|
||||
const { isFloatWindow } = toRefs(useFloatWindowContext());
|
||||
const { localUserInfoExcludeVolume, remoteUserListExcludeVolume } = toRefs(useUserInfoExcludeVolumeContext());
|
||||
|
||||
const handleShowSelectUser = async (value: boolean) => {
|
||||
showSelectUser.value = value;
|
||||
if (showSelectUser.value) {
|
||||
await getGroupMemberList();
|
||||
const groupProfile = await TUICallKitAPI.getGroupProfile();
|
||||
memberCount.value = groupProfile.memberCount;
|
||||
}
|
||||
}
|
||||
const handleCancel = () => {
|
||||
showSelectUser.value = false;
|
||||
TUIStore.update(StoreName.CALL, NAME.SHOW_SELECT_USER, false);
|
||||
offset.value = 0;
|
||||
groupMemberList.value = [];
|
||||
}
|
||||
const getMoreMemberList = async () => {
|
||||
offset.value += count;
|
||||
await getGroupMemberList();
|
||||
}
|
||||
const getGroupMemberList = async () => {
|
||||
const memberList = await TUICallKitAPI.getGroupMemberList(count, offset.value);
|
||||
const inCallUserIdList = [...remoteUserListExcludeVolume.value, localUserInfoExcludeVolume.value].map(obj => obj.userId);
|
||||
groupMemberList.value.push(...memberList);
|
||||
groupMemberList.value = groupMemberList.value.map(obj => {
|
||||
if (inCallUserIdList.includes(obj.userID)) {
|
||||
obj = { ...obj, isDisabled: true };
|
||||
}
|
||||
return obj;
|
||||
});
|
||||
backupGroupMemberList.value = groupMemberList.value;
|
||||
};
|
||||
const handleSelectedResult = async (selectedUserInfoList: Array<any>) => {
|
||||
try {
|
||||
if (selectedUserInfoList.length <= 0) {
|
||||
return ;
|
||||
}
|
||||
showSelectUser.value = false;
|
||||
TUIStore.update(StoreName.CALL, NAME.SHOW_SELECT_USER, false);
|
||||
offset.value = 0;
|
||||
const userIDList = selectedUserInfoList.map(obj => obj.userID);
|
||||
await TUICallKitAPI.inviteUser({userIDList});
|
||||
groupMemberList.value = [];
|
||||
} catch (error) {
|
||||
console.debug(error);
|
||||
}
|
||||
};
|
||||
const handleSearch = (searchValue: string) => {
|
||||
if (searchValue) {
|
||||
groupMemberList.value = groupMemberList.value.filter(obj => {
|
||||
return obj.userID.includes(searchValue) || obj.nick.includes(searchValue)
|
||||
});
|
||||
} else {
|
||||
groupMemberList.value = backupGroupMemberList.value;
|
||||
}
|
||||
};
|
||||
|
||||
const watchOptions = {
|
||||
[NAME.SHOW_SELECT_USER]: handleShowSelectUser,
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
TUIStore.watch(StoreName.CALL, watchOptions, { notifyRangeWhenWatch: NAME.MYSELF });
|
||||
});
|
||||
onUnmounted(() => {
|
||||
TUIStore.unwatch(StoreName.CALL, watchOptions);
|
||||
});
|
||||
|
||||
ButtonPanelContextValue.status = ref('open');
|
||||
FocusContextValue.value = null;
|
||||
provide(ButtonPanelContextKey, ButtonPanelContextValue);
|
||||
provide(FocusContextKey, FocusContextValue);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.groupcall-container {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,267 @@
|
||||
<template>
|
||||
<Portal id="source" :disabled="!isFloatWindow" source="#source" to="body">
|
||||
<FloatWindow>
|
||||
<div
|
||||
:class="groupMediaContainerClassName"
|
||||
:style="[mediaContainerStyle]"
|
||||
>
|
||||
<Grid
|
||||
:unit="unit"
|
||||
:enable-focus="enableFocus"
|
||||
:focus="focus"
|
||||
:length="streamLength"
|
||||
:layout="layout"
|
||||
@toggle="changeFocus"
|
||||
>
|
||||
<GridItem :index="0" :key="localUserInfoExcludeVolume.userId">
|
||||
<Pusher
|
||||
:domId="localUserInfoExcludeVolume.domId"
|
||||
:show-audio-stream="!localUserInfoExcludeVolume.isVideoAvailable"
|
||||
:show="visibleStreamIdList.includes(localUserInfoExcludeVolume.domId) && showStream"
|
||||
>
|
||||
<template v-slot:audio-stream>
|
||||
<AudioStream
|
||||
:user-id="localUserInfoExcludeVolume.userId"
|
||||
:username="localUserInfoExcludeVolume.displayUserInfo"
|
||||
:avatar="localUserInfoExcludeVolume.avatar"
|
||||
:is-video-available="localUserInfoExcludeVolume.isVideoAvailable"
|
||||
/>
|
||||
</template>
|
||||
<template v-slot:loading>
|
||||
<StreamLoading v-if="isPusherLoading" />
|
||||
</template>
|
||||
<template v-slot:stream-info>
|
||||
<TKStreamInfo
|
||||
v-if="!isFloatWindow"
|
||||
:is-self="true"
|
||||
:show-nick-name="showNickName"
|
||||
:showSwitchCameraButton="showSwitchCameraButton"
|
||||
:showVirtualBackgroundButton="showVirtualBackgroundButton"
|
||||
:showNetWorkStatus="isShowNetWork(localUserInfoExcludeVolume.userId)"
|
||||
:nickName="localUserInfoExcludeVolume.displayUserInfo"
|
||||
:isMuted="!localUserInfoExcludeVolume.isAudioAvailable"
|
||||
:volume="volumeMap && volumeMap[localUserInfoExcludeVolume.domId]"
|
||||
/>
|
||||
</template>
|
||||
</Pusher>
|
||||
</GridItem>
|
||||
<GridItem v-for="(remoteStreamItem, index) in remoteUserListExcludeVolume" :key="remoteStreamItem.userId" :index="index + 1">
|
||||
<Player
|
||||
:domId="remoteStreamItem.domId"
|
||||
:show-audio-stream="isShowAudioStream(remoteStreamItem)"
|
||||
:show="visibleStreamIdList.includes(remoteStreamItem.domId) && showStream"
|
||||
>
|
||||
<template v-slot:audio-stream>
|
||||
<AudioStream
|
||||
:user-id="remoteStreamItem.userId"
|
||||
:username="remoteStreamItem.displayUserInfo"
|
||||
:avatar="remoteStreamItem.avatar"
|
||||
/>
|
||||
</template>
|
||||
<template v-slot:loading>
|
||||
<StreamLoading v-if="!remoteStreamItem.isEnter" />
|
||||
</template>
|
||||
<template v-slot:stream-info>
|
||||
<TKStreamInfo
|
||||
v-if="!isFloatWindow"
|
||||
:show-nick-name="TUIGlobal.isPC || String(focus) === String(index + 1)"
|
||||
:show-control-button="false"
|
||||
:showNetWorkStatus="isShowNetWork(remoteStreamItem.userId)"
|
||||
:nickName="remoteStreamItem.displayUserInfo"
|
||||
:is-muted="isMute(remoteStreamItem)"
|
||||
:volume="volumeMap && volumeMap[remoteStreamItem.domId]"
|
||||
/>
|
||||
</template>
|
||||
</Player>
|
||||
</GridItem>
|
||||
</Grid>
|
||||
</div>
|
||||
</FloatWindow>
|
||||
</Portal>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
virtualHost: true,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, toRefs, computed } from '../../../../adapter-vue';
|
||||
import { CallMediaType, CallStatus, TUIGlobal, CallRole } from '../../../../TUICallService';
|
||||
import Pusher from '../../common/Pusher/Pusher.vue';
|
||||
import Player from '../../common/Player/Player.vue';
|
||||
import Grid from '../../base/Grid/Grid.vue';
|
||||
import GridItem from '../../base/Grid/GridItem/GridItem.vue';
|
||||
import AudioStream from '../../common/AudioStream/AudioStream.vue';
|
||||
import TKStreamInfo from '../../common/TKStreamInfo/TKStreamInfo.vue';
|
||||
import FloatWindow from '../../common/FloatWindow/FloatWindow.vue';
|
||||
import Portal from '../../base/Portal/Portal.vue';
|
||||
import {
|
||||
useUserInfoExcludeVolumeContext,
|
||||
useCallInfoContext,
|
||||
usePlayer,
|
||||
useGetVolumeMap,
|
||||
useFloatWindowContext,
|
||||
useFocusContext,
|
||||
useButtonPanelStatus,
|
||||
useGroupCallLayout,
|
||||
useCustomUI,
|
||||
useNetWorkStatus
|
||||
} from '../../../hooks';
|
||||
import { classNames } from '../../base/util';
|
||||
import StreamLoading from './StreamLoading/StreamLoading.vue';
|
||||
|
||||
const bigWindow = ref('local');
|
||||
const showSmallWindow = ref(false);
|
||||
const customUI = useCustomUI();
|
||||
|
||||
const { localUserInfoExcludeVolume, remoteUserListExcludeVolume } = toRefs(useUserInfoExcludeVolumeContext());
|
||||
const { callStatus, callType, isShowEnableVirtualBackground, callRole } = toRefs(useCallInfoContext());
|
||||
const focus = ref(TUIGlobal.isPC
|
||||
? null
|
||||
: callType.value === CallMediaType.VIDEO ? 0 : null); // video call localView default big
|
||||
const { netWorkQualityList } = useNetWorkStatus();
|
||||
const streamLength = computed(() => remoteUserListExcludeVolume.value.length + 1);
|
||||
const wxPlayer = usePlayer();
|
||||
const layout = useGroupCallLayout(focus, streamLength);
|
||||
const volumeMap = useGetVolumeMap();
|
||||
const { isFloatWindow } = toRefs(useFloatWindowContext());
|
||||
const focusElement = useFocusContext();
|
||||
const { status: panelStatus } = useButtonPanelStatus() || {};
|
||||
const enableFocus = !TUIGlobal.isPC;
|
||||
const isCurrentUserStreamZoomIn = computed(() => String(focus.value) === '0');
|
||||
const showControlButton = computed(() => !TUIGlobal.isPC && isCurrentUserStreamZoomIn.value && localUserInfoExcludeVolume.value.isVideoAvailable)
|
||||
|
||||
const showSwitchCameraButton = computed(() => showControlButton.value);
|
||||
const showVirtualBackgroundButton = computed(() => showControlButton.value && isShowEnableVirtualBackground.value && TUIGlobal.isWeChat);
|
||||
const showNickName = computed(() => TUIGlobal.isPC || isCurrentUserStreamZoomIn.value);
|
||||
const unit = computed(() => (TUIGlobal.isPC || isFloatWindow.value) ? '%' : 'vw');
|
||||
const visibleStreamIdList = computed(() => {
|
||||
return [localUserInfoExcludeVolume.value, ...remoteUserListExcludeVolume.value].map((stream) => {
|
||||
if (isFloatWindow.value) {
|
||||
if (volumeMap.value?.[stream.domId] >= 10) {
|
||||
return stream.domId;
|
||||
}
|
||||
} else {
|
||||
return stream.domId;
|
||||
}
|
||||
});
|
||||
});
|
||||
const showStream = computed(() => !(
|
||||
callRole.value === CallRole.CALLEE
|
||||
&& callStatus.value === CallStatus.CALLING
|
||||
&& !isFloatWindow.value
|
||||
));
|
||||
|
||||
const mediaContainerStyle = computed(() => {
|
||||
let visibility = '';
|
||||
|
||||
if (callRole.value === CallRole.CALLEE && callStatus.value === CallStatus.CALLING && !isFloatWindow.value) {
|
||||
visibility = 'hidden';
|
||||
}
|
||||
|
||||
return {
|
||||
visibility,
|
||||
}
|
||||
});
|
||||
|
||||
function changeFocus(value) {
|
||||
focus.value = value;
|
||||
focusElement.value = value;
|
||||
panelStatus.value = value !== null ? 'close' : 'open';
|
||||
}
|
||||
|
||||
function isShowAudioStream(stream) {
|
||||
return !stream.isVideoAvailable;
|
||||
}
|
||||
|
||||
function isMute(stream) {
|
||||
return !stream.isAudioAvailable;
|
||||
}
|
||||
|
||||
function isShowNetWork(userId) {
|
||||
if(!netWorkQualityList.value) return;
|
||||
const isRemoteUser = userId !== localUserInfoExcludeVolume.value.userId;
|
||||
if(!TUIGlobal.isWeChat && isRemoteUser) return;
|
||||
const targetNetwork = netWorkQualityList.value.find(item => item.userId === userId);
|
||||
return targetNetwork && targetNetwork?.quality >= 4;
|
||||
}
|
||||
|
||||
watch([remoteUserListExcludeVolume, callType], () => {
|
||||
if (remoteUserListExcludeVolume.value?.[0]?.isEnter) {
|
||||
bigWindow.value = 'remote';
|
||||
}
|
||||
|
||||
if (callType.value === CallMediaType.AUDIO) {
|
||||
showSmallWindow.value = false;
|
||||
} else {
|
||||
showSmallWindow.value = true;
|
||||
}
|
||||
});
|
||||
const groupMediaContainerClassName = computed(() => classNames([
|
||||
'groupcall-media-container',
|
||||
{
|
||||
mobile: !TUIGlobal.isPC,
|
||||
pc: TUIGlobal.isPC,
|
||||
'two-layout': streamLength.value === 2 && focus.value === null,
|
||||
float: isFloatWindow.value,
|
||||
}
|
||||
]));
|
||||
const isPusherLoading = computed(() => {
|
||||
if (callStatus.value === CallStatus.CALLING) {
|
||||
if ((callType.value === CallMediaType.AUDIO && !localUserInfoExcludeVolume.value.isAudioAvailable)
|
||||
|| (callType.value === CallMediaType.VIDEO && !localUserInfoExcludeVolume.value.isVideoAvailable)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.groupcall-media-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
&.pc {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
|
||||
&.two-layout {
|
||||
margin-top: 20%;
|
||||
}
|
||||
|
||||
.tk-toggle-window-item--small {
|
||||
top: 2%;
|
||||
left: 2%;
|
||||
width: 22%;
|
||||
height: 21%;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&.mobile {
|
||||
margin-top: 5.5vh;
|
||||
|
||||
&.float {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&.two-layout {
|
||||
margin-top: 15vh;
|
||||
|
||||
&.float {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
<template>
|
||||
<div class="stream-loading-container">
|
||||
<Loading mode="dot" color="#FFF" loadingWidth="50px" loadingHeight="50px" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Loading from '../../../base/Loading/Loading.vue';
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.stream-loading-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<Portal id="source" :disabled="!isFloatWindow" source="#source" to="body">
|
||||
<FloatWindow>
|
||||
<div :class="singleMediaContainerClassName">
|
||||
<ToggleWindow
|
||||
:big-window="largeViewName"
|
||||
:show-small-window="showSmallWindow"
|
||||
@toggle="handleToggle"
|
||||
>
|
||||
<ToggleWindowItem :value="ViewName.LOCAL" :key="ViewName.LOCAL">
|
||||
<Pusher
|
||||
:domId="localUserInfoExcludeVolume.domId"
|
||||
:show-audio-stream="!localUserInfoExcludeVolume.isVideoAvailable"
|
||||
>
|
||||
<template v-slot:audio-stream>
|
||||
<AudioStream
|
||||
:userId="localUserInfoExcludeVolume.userId"
|
||||
:username="localUserInfoExcludeVolume.displayUserInfo"
|
||||
:avatar="localUserInfoExcludeVolume.avatar"
|
||||
:is-video-available="localUserInfoExcludeVolume.isVideoAvailable"
|
||||
:is-small-window="!(largeViewName === ViewName.LOCAL)"
|
||||
:is-muted="!localUserInfoExcludeVolume.isAudioAvailable"
|
||||
:volume="volumeMap && volumeMap[localUserInfoExcludeVolume.domId]"
|
||||
/>
|
||||
</template>
|
||||
<template v-slot:stream-info>
|
||||
<TKStreamInfo
|
||||
v-if="callType === CallMediaType.VIDEO"
|
||||
:nick-name="localUserInfoExcludeVolume.displayUserInfo"
|
||||
:is-self="true"
|
||||
:is-muted="!localUserInfoExcludeVolume.isAudioAvailable"
|
||||
:volume="volumeMap && volumeMap[localUserInfoExcludeVolume.domId]"
|
||||
/>
|
||||
</template>
|
||||
</Pusher>
|
||||
</ToggleWindowItem>
|
||||
<ToggleWindowItem :value="ViewName.REMOTE" :key="ViewName.REMOTE">
|
||||
<Player
|
||||
:dom-id="playerDomId"
|
||||
:show-audio-stream="!isPusherVideoAvailable"
|
||||
>
|
||||
<template v-slot:audio-stream>
|
||||
<AudioStream
|
||||
:userId="remoteUserListExcludeVolume[0] && remoteUserListExcludeVolume[0].userId"
|
||||
:username="remoteUserListExcludeVolume[0] && remoteUserListExcludeVolume[0].displayUserInfo"
|
||||
:avatar="remoteUserListExcludeVolume[0] && remoteUserListExcludeVolume[0].avatar"
|
||||
:is-video-available="isPusherVideoAvailable"
|
||||
:is-small-window="!(largeViewName === ViewName.REMOTE)"
|
||||
:is-muted="remoteUserListExcludeVolume[0] && !remoteUserListExcludeVolume[0].isAudioAvailable"
|
||||
:volume="remoteStreamVolume"
|
||||
/>
|
||||
</template>
|
||||
<template v-slot:stream-info>
|
||||
<TKStreamInfo
|
||||
v-if="callType === CallMediaType.VIDEO"
|
||||
:nick-name="remoteUserListExcludeVolume[0] && remoteUserListExcludeVolume[0].displayUserInfo"
|
||||
:is-muted="remoteUserListExcludeVolume[0] && !remoteUserListExcludeVolume[0].isAudioAvailable"
|
||||
:volume="remoteStreamVolume"
|
||||
/>
|
||||
</template>
|
||||
</Player>
|
||||
</ToggleWindowItem>
|
||||
</ToggleWindow>
|
||||
</div>
|
||||
</FloatWindow>
|
||||
</Portal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
virtualHost: true,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, toRefs, computed } from '../../../../adapter-vue';
|
||||
import { CallMediaType, CallStatus, TUIGlobal } from '../../../../TUICallService';
|
||||
import ToggleWindow from '../../base/ToggleWindow/ToggleWindow.vue';
|
||||
import Portal from '../../base/Portal/Portal.vue';
|
||||
import ToggleWindowItem from '../../base/ToggleWindow/ToggleWindowItem/ToggleWindowItem.vue';
|
||||
import TKStreamInfo from '../../common/TKStreamInfo/TKStreamInfo.vue';
|
||||
import Pusher from '../../common/Pusher/Pusher.vue';
|
||||
import Player from '../../common/Player/Player.vue';
|
||||
import AudioStream from '../../common/AudioStream/AudioStream.vue';
|
||||
import FloatWindow from '../../common/FloatWindow/FloatWindow.vue';
|
||||
import {
|
||||
useUserInfoExcludeVolumeContext,
|
||||
useCallInfoContext,
|
||||
useGetVolumeMap,
|
||||
usePlayer,
|
||||
useFloatWindowContext,
|
||||
} from '../../../hooks';
|
||||
import { useGetLargeViewName } from '../hooks/useGetLargeViewName';
|
||||
import { classNames } from '../../base/util';
|
||||
import { ViewName } from '../../../../TUICallService/const/index';
|
||||
|
||||
const largeViewName = useGetLargeViewName();
|
||||
const showSmallWindow = ref(true);
|
||||
const { isFloatWindow } = toRefs(useFloatWindowContext());
|
||||
function toggle() {
|
||||
isFloatWindow.value = !isFloatWindow.value;
|
||||
}
|
||||
const { localUserInfoExcludeVolume, remoteUserListExcludeVolume } = toRefs(useUserInfoExcludeVolumeContext());
|
||||
const volumeMap = useGetVolumeMap();
|
||||
const { callType, callStatus } = toRefs(useCallInfoContext());
|
||||
const wxPlayer = usePlayer();
|
||||
|
||||
const isPusherVideoAvailable = computed(() => remoteUserListExcludeVolume.value?.[0]?.isVideoAvailable);
|
||||
|
||||
const playerDomId = computed(() => remoteUserListExcludeVolume.value?.[0]?.domId);
|
||||
const remoteStreamVolume = computed(() => volumeMap.value?.[remoteUserListExcludeVolume.value?.[0]?.domId]);
|
||||
|
||||
watch([callType, callStatus], () => {
|
||||
if (callType.value === CallMediaType.AUDIO || callStatus.value === CallStatus.CALLING) {
|
||||
showSmallWindow.value = false;
|
||||
} else {
|
||||
showSmallWindow.value = true;
|
||||
}
|
||||
}, {
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
const singleMediaContainerClassName = computed(() => classNames([
|
||||
'singlecall-media-container',
|
||||
{
|
||||
mobile: !TUIGlobal.isPC,
|
||||
pc: TUIGlobal.isPC,
|
||||
float: isFloatWindow.value,
|
||||
}
|
||||
]));
|
||||
|
||||
function handleToggle(value) {
|
||||
largeViewName.value = value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.singlecall-media-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
&.float {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&.pc {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
.roggle-btn {
|
||||
position: absolute;
|
||||
left: 100px;
|
||||
z-index: 100;
|
||||
top: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<div class="singlecall-container">
|
||||
<TopBar />
|
||||
<Waiting v-if="callStatus === CallStatus.CALLING" />
|
||||
<MediaContainer />
|
||||
<Tip />
|
||||
<ButtonPanel />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { toRefs } from '../../../adapter-vue';
|
||||
import { CallStatus } from '../../../TUICallService';
|
||||
import TopBar from '../common/TopBar/TopBar.vue';
|
||||
import Waiting from '../common/Waiting/Waiting.vue';
|
||||
import MediaContainer from './MediaContainer/MediaContainer.vue';
|
||||
import Tip from '../common/Tip/Tip.vue';
|
||||
import ButtonPanel from '../common/ButtonPanel/ButtonPanel.vue';
|
||||
import { useCallInfoContext } from '../../hooks';
|
||||
|
||||
const { callStatus } = toRefs(useCallInfoContext());
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.singlecall-container {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,32 @@
|
||||
import { CallStatus, LayoutMode, ViewName } from '../../../../TUICallService/const';
|
||||
import { ref, watch, toRefs } from '../../../../adapter-vue';
|
||||
import { useCallInfoContext, useCustomUI, useUserInfoExcludeVolumeContext } from '../../../hooks';
|
||||
|
||||
export function useGetLargeViewName() {
|
||||
const config = useCustomUI();
|
||||
const { callStatus } = toRefs(useCallInfoContext());
|
||||
const largeViewName = ref(ViewName.LOCAL);
|
||||
const { remoteUserListExcludeVolume } = toRefs(useUserInfoExcludeVolumeContext());
|
||||
|
||||
watch([remoteUserListExcludeVolume, config, callStatus], () => {
|
||||
if (callStatus.value === CallStatus.CALLING) {
|
||||
return;
|
||||
}
|
||||
|
||||
const c2cLayoutModes = [LayoutMode.RemoteInLargeView, LayoutMode.LocalInLargeView];
|
||||
const customLayoutMode = config.value?.layoutMode;
|
||||
if (c2cLayoutModes.includes(customLayoutMode)) {
|
||||
// @ts-ignore
|
||||
largeViewName.value = config.value?.layoutMode;
|
||||
return;
|
||||
}
|
||||
|
||||
if (remoteUserListExcludeVolume.value?.[0]?.isEnter) {
|
||||
largeViewName.value = ViewName.REMOTE;
|
||||
}
|
||||
}, {
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
return largeViewName;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
const Fit = ['fill', 'contain', 'cover'] as const;
|
||||
const Shape = ['circle', 'square'] as const;
|
||||
|
||||
export const AvatarProps = {
|
||||
icon: {
|
||||
type: String,
|
||||
},
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 100,
|
||||
},
|
||||
shape: {
|
||||
type: String,
|
||||
values: Shape,
|
||||
default: 'square',
|
||||
},
|
||||
src: {
|
||||
type: String,
|
||||
},
|
||||
defaultSrc: {
|
||||
type: String,
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
},
|
||||
fit: {
|
||||
type: String,
|
||||
values: Fit,
|
||||
default: 'cover',
|
||||
},
|
||||
customClass: {
|
||||
type: String,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const avatarEmits = {
|
||||
error: (evt) => evt,
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div :class="classname" :style="[avatarStyle]">
|
||||
<TKImage v-if="avatarSrc" :fit="fit" :width="width" :height="height" :src="avatarSrc" @error="handleError" />
|
||||
<slot v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
virtualHost: true,
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from '../../../../adapter-vue';
|
||||
import TKImage from '../TKImage/TKImage.vue';
|
||||
import { classNames } from '../util';
|
||||
import { AvatarProps } from './Avatar';
|
||||
import { PREFIX } from '../constants/index';
|
||||
|
||||
const props = defineProps(AvatarProps);
|
||||
|
||||
const avatarSrc = ref('');
|
||||
|
||||
watch(() => props.src, () => {
|
||||
avatarSrc.value = props.src;
|
||||
}, {
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
const classname = computed(() => classNames([
|
||||
`${PREFIX}-avatar`,
|
||||
`${PREFIX}-avatar--${props.shape}`,
|
||||
`${PREFIX}-avatar--${props.size}`,
|
||||
props.customClass,
|
||||
]));
|
||||
const width = computed(() => typeof props.size === 'number' ? `${props.size}px` : props.size);
|
||||
const height = computed(() => typeof props.size === 'number' ? `${props.size}px` : props.size);
|
||||
const avatarStyle = computed(() => ({ width: width.value, height: height.value }));
|
||||
|
||||
function handleError(e) {
|
||||
console.error(e);
|
||||
if (props.defaultSrc) {
|
||||
avatarSrc.value = props.defaultSrc;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import './style/Avatar.scss';
|
||||
</style>
|
||||
@@ -0,0 +1,40 @@
|
||||
@import '../../styles/var.scss';
|
||||
@import '../../styles/common.scss';
|
||||
|
||||
$--tk-avatar-text-color: $--tk-color-white;
|
||||
$--tk-avatar-bg-color: $--tk-text-color-disabled;
|
||||
$--tk-avatar-text-size: 14px;
|
||||
$--tk-avatar-icon-size: 18px;
|
||||
$--tk-avatar-border-radius: $--tk-border-radius-base;
|
||||
$--tk-avatar-size-large: 56px;
|
||||
$--tk-avatar-size-small: 24px;
|
||||
$--tk-avatar-size: 40px;
|
||||
|
||||
.#{$PREFIX}-avatar {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
color: $--tk-avatar-text-color;
|
||||
background: $--tk-avatar-bg-color;
|
||||
width: $--tk-avatar-size;
|
||||
height: $--tk-avatar-size;
|
||||
font-size: $--tk-avatar-text-size;
|
||||
|
||||
&.#{$PREFIX}-avatar--square {
|
||||
border-radius: $--tk-avatar-border-radius;
|
||||
}
|
||||
&.#{$PREFIX}-avatar--circle {
|
||||
border-radius: $--tk-border-radius-circle;
|
||||
}
|
||||
.#{$PREFIX}-avatar_img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.#{$PREFIX}-avatar_image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
const Size = ['small','middle','large'] as const;
|
||||
const Direction = ['row','column'] as const;
|
||||
const Shape = ['circle','round'] as const;
|
||||
|
||||
export const ButtonProps = {
|
||||
iconSrc: {
|
||||
type: String,
|
||||
},
|
||||
iconSize: {
|
||||
type: Number,
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loadingColor: {
|
||||
type: String,
|
||||
default: '#fff',
|
||||
},
|
||||
loadingWidth: {
|
||||
type: String,
|
||||
default: '40px',
|
||||
},
|
||||
loadingHeight: {
|
||||
type: String,
|
||||
default: '40px',
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
values: Size,
|
||||
default: 'middle',
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
values: Direction,
|
||||
default: 'row',
|
||||
},
|
||||
shape: {
|
||||
type: String,
|
||||
values: Shape,
|
||||
},
|
||||
buttonStyle: {
|
||||
type: Object,
|
||||
},
|
||||
buttonTextStyle: {
|
||||
type: Object,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
<template>
|
||||
<div :style="[style]" :class="buttonClassName" @click="handleClick">
|
||||
<Loading
|
||||
v-if="loading"
|
||||
:loadingWidth="loadingWidth"
|
||||
:loadingHeight="loadingHeight"
|
||||
:color="loadingColor"
|
||||
/>
|
||||
<Icon v-if="iconSrc && !loading" :size="iconSize" :src="iconSrc"></Icon>
|
||||
<div
|
||||
v-if="text"
|
||||
:style="[buttonTextStyle]"
|
||||
:class="buttonTextClassName"
|
||||
>
|
||||
{{ text }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
virtualHost: true,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from '../../../../adapter-vue';
|
||||
import Loading from '../Loading/Loading.vue';
|
||||
import Icon from '../Icon/Icon.vue';
|
||||
import { classNames, IS_PC } from '../util';
|
||||
import { ButtonProps } from './Button';
|
||||
import { PREFIX } from '../constants/index';
|
||||
|
||||
const props = defineProps(ButtonProps);
|
||||
const buttonTextClassName = `${PREFIX}-button--content`;
|
||||
const style = computed(() => ({
|
||||
width: props.width,
|
||||
height: props.height,
|
||||
backgroundColor: props.color,
|
||||
flexDirection: props.direction,
|
||||
cursor: IS_PC ? 'pointer' : 'auto',
|
||||
...props.buttonStyle,
|
||||
}));
|
||||
|
||||
const buttonClassName = classNames([
|
||||
`${PREFIX}-button`,
|
||||
{[`${PREFIX}-${props.shape}`]: props.shape},
|
||||
`${PREFIX}-button--${props.size}`
|
||||
]);
|
||||
|
||||
const emit = defineEmits(['click']);
|
||||
const handleClick = (event) => {
|
||||
!props.loading && emit('click', event);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import './style/Button.scss';
|
||||
</style>
|
||||
@@ -0,0 +1,42 @@
|
||||
@import '../../styles/var.scss';
|
||||
@import '../../styles/common.scss';
|
||||
|
||||
$--tk-button-size-default: $--tk-button-size-middle;
|
||||
|
||||
.#{$PREFIX}-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.#{$PREFIX}-button--small {
|
||||
height: $--tk-button-size-small;
|
||||
}
|
||||
|
||||
&.#{$PREFIX}-button--middle {
|
||||
height: $--tk-button-size-middle;
|
||||
}
|
||||
|
||||
&.#{$PREFIX}-button--large {
|
||||
height: $--tk-button-size-large;
|
||||
}
|
||||
|
||||
.#{$PREFIX}-button--content {
|
||||
color: $--tk-text-color-regular;
|
||||
font-size: $--tk-font-size-base;
|
||||
font-weight: $--tk-font-weight-primary;
|
||||
}
|
||||
|
||||
&.#{$PREFIX}-circle {
|
||||
&.#{$PREFIX}-button--small {
|
||||
width: $--tk-button-size-small;
|
||||
}
|
||||
|
||||
&.#{$PREFIX}-button--default {
|
||||
width: $--tk-button-size-default;
|
||||
}
|
||||
|
||||
&.#{$PREFIX}-button--large {
|
||||
width: $--tk-button-size-large;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
const Unit = ['%', 'vw'];
|
||||
|
||||
export const GridProps = {
|
||||
length: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
unit: {
|
||||
type: String,
|
||||
values: Unit,
|
||||
default: '%',
|
||||
},
|
||||
enableFocus: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
layout: {
|
||||
type: Array,
|
||||
},
|
||||
focus: {
|
||||
type: [String, Number],
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const ChangeFocusEmits = ['change', 'toggle'];
|
||||
export const GridContextKey = 'GridContextKey';
|
||||
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div :style="{ height: '100%'}">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
virtualHost: true
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { provide, watch, ref } from '../../../../adapter-vue';
|
||||
import { ChangeFocusEmits, GridContextKey, GridProps } from './Grid';
|
||||
|
||||
const props = defineProps(GridProps);
|
||||
const focus = ref(props.focus);
|
||||
const layout = ref(props.layout);
|
||||
const unit = ref(props.unit);
|
||||
const emit = defineEmits(ChangeFocusEmits);
|
||||
|
||||
function handleFocusChange(value) {
|
||||
emit('toggle', value);
|
||||
}
|
||||
|
||||
watch(() => props.focus, () => focus.value = props.focus);
|
||||
watch(() => props.layout, () => layout.value = props.layout);
|
||||
watch(() => props.unit, () => unit.value = props.unit);
|
||||
|
||||
provide(GridContextKey, {
|
||||
layout,
|
||||
enableFocus: props.enableFocus,
|
||||
handleFocusChange,
|
||||
focus,
|
||||
unit,
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="show"
|
||||
:class="gridItemClassName"
|
||||
:style="[style]"
|
||||
@click="handleClick"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
virtualHost: true
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { inject, computed, ref, watchEffect, watch, onUnmounted } from '../../../../../adapter-vue';
|
||||
import { GridContextKey } from '../Grid';
|
||||
import { PREFIX } from '../../constants/index';
|
||||
import { IS_PC, IS_H5, classNames, findTarget } from '../../util';
|
||||
|
||||
const props = defineProps(['index', 'height', 'customStyle']);
|
||||
const {
|
||||
layout,
|
||||
enableFocus,
|
||||
handleFocusChange,
|
||||
focus,
|
||||
unit,
|
||||
} = inject(GridContextKey);
|
||||
|
||||
const colWidth = 100 / 12;
|
||||
const rowHeight = colWidth;
|
||||
const style = ref({});
|
||||
const gridItemClassName = classNames([
|
||||
`${PREFIX}-grid-item`,
|
||||
{
|
||||
pc: IS_PC,
|
||||
mobile: !IS_PC,
|
||||
h5: IS_H5,
|
||||
},
|
||||
]);
|
||||
|
||||
const handleClick = () => {
|
||||
const value = String(props.index) === String(focus.value) ? null : props.index;
|
||||
enableFocus && handleFocusChange(value);
|
||||
};
|
||||
|
||||
const show = computed(() => !!findTarget(layout.value, { key: 'i', value: props.index}));
|
||||
|
||||
watchEffect(() => {
|
||||
const target = findTarget(layout.value, { key: 'i', value: props.index});
|
||||
|
||||
if (!target) return;
|
||||
|
||||
const { x, y, w, h, customStyle, customProps } = target;
|
||||
style.value = {
|
||||
width: w * colWidth + unit.value,
|
||||
height: props.height || h * rowHeight + unit.value,
|
||||
left: x * colWidth + unit.value,
|
||||
top: y * rowHeight + unit.value,
|
||||
position: 'absolute',
|
||||
visibility: customProps?.show === false ? 'hidden' : '',
|
||||
...props.customStyle,
|
||||
...customStyle,
|
||||
};
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (String(props.index) === String(focus.value)) {
|
||||
enableFocus && handleFocusChange(null);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import './style/GridItem.scss';
|
||||
</style>
|
||||
@@ -0,0 +1,13 @@
|
||||
@import '../../../styles/common.scss';
|
||||
@import '../../../styles/var.scss';
|
||||
|
||||
.#{$PREFIX}-grid-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
&.h5 {
|
||||
transition-property: width,height,left,top;
|
||||
transition-duration: 0.3s;
|
||||
transition-timing-function: ease-in;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export const IconProps = {
|
||||
src: {
|
||||
type: String
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<TKImage :src="src" :width="width" :height="height"></TKImage>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
virtualHost: true,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from '../../../../adapter-vue';
|
||||
import { IconProps } from './Icon';
|
||||
import TKImage from '../TKImage/TKImage.vue';
|
||||
|
||||
const props = defineProps(IconProps);
|
||||
const width = computed(() => `${props.size}px`);
|
||||
const height = computed(() => `${props.size}px`);
|
||||
</script>
|
||||
@@ -0,0 +1,23 @@
|
||||
const ColJustify = ['start', 'center', 'end', 'space-around', 'space-between', 'space-evenly'] as const;
|
||||
const ColAlign = ['top', 'middle', 'bottom'] as const;
|
||||
|
||||
export const colProps = {
|
||||
span: {
|
||||
type: Number,
|
||||
default: 24,
|
||||
},
|
||||
justify: {
|
||||
type: String,
|
||||
values: ColJustify,
|
||||
default: 'start',
|
||||
},
|
||||
align: {
|
||||
type: String,
|
||||
values: ColAlign,
|
||||
default: 'middle',
|
||||
},
|
||||
offset: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div
|
||||
:class="classname"
|
||||
:style="{
|
||||
width,
|
||||
marginLeft,
|
||||
paddingLeft,
|
||||
paddingRight,
|
||||
}">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
virtualHost: true
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, inject } from '../../../../../adapter-vue';
|
||||
import { classNames } from '../../util';
|
||||
import { colProps } from './Col';
|
||||
import { RowContextKey } from '../constant';
|
||||
import { PREFIX } from '../../constants/index';
|
||||
|
||||
const props = defineProps(colProps);
|
||||
const { gutter } = inject(RowContextKey, { gutter: computed(() => 0)});
|
||||
|
||||
const classname = classNames([
|
||||
`${PREFIX}-col`,
|
||||
`${PREFIX}-justify-${props.justify}`,
|
||||
`${PREFIX}-align-${props.align}`,
|
||||
]);
|
||||
|
||||
const width = computed(() => `${props.span / 24 * 100}%`);
|
||||
const marginLeft = computed(() => `${props.offset / 24 * 100}%`);
|
||||
const paddingLeft = computed(() => `${gutter.value / 2}px`);
|
||||
const paddingRight = paddingLeft;
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import './style/Col.scss';
|
||||
</style>
|
||||