feat: ✨新增vitepress文档
@ -1,6 +0,0 @@
|
||||
import Prism from 'prism-react-renderer/prism';
|
||||
|
||||
(typeof global !== 'undefined' ? global : window).Prism = Prism;
|
||||
|
||||
require('prismjs/components/prism-kotlin');
|
||||
require('prismjs/components/prism-java');
|
@ -1,145 +0,0 @@
|
||||
import React, { useRef } from 'react';
|
||||
import './style.scss';
|
||||
|
||||
import { usePrefersColor } from 'dumi/dist/client/theme-api/usePrefersColor';
|
||||
|
||||
const Home: any = () => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [color] = usePrefersColor();
|
||||
|
||||
// mount
|
||||
React.useEffect(() => {
|
||||
document.title = '悟空IM';
|
||||
const element = document.getElementById('root')
|
||||
element?.setAttribute('home', 'true')
|
||||
|
||||
const logoElement = document.querySelector('.dumi-default-logo img');
|
||||
logoElement?.setAttribute('src', '/logo_white.png')
|
||||
return () => {
|
||||
const element = document.getElementById('root')
|
||||
element?.removeAttribute('home')
|
||||
|
||||
logoElement?.setAttribute('src', '/logo.png')
|
||||
};
|
||||
}, []);
|
||||
|
||||
var isPhone = true
|
||||
if (/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) {
|
||||
isPhone = true
|
||||
} else {
|
||||
isPhone = false
|
||||
}
|
||||
|
||||
var item1 = {
|
||||
icon: './././imgs/ic_no_dependency.png',
|
||||
title: '零依赖',
|
||||
desc: '没有依赖任何第三方组件,部署简单,一条命令即可启动'
|
||||
}
|
||||
var item2 = {
|
||||
icon: './././imgs/ic_self_developed.png',
|
||||
title: '完全自研',
|
||||
desc: '自研消息数据库,消息分区永久存储,自研二进制协议,支持自定义协议'
|
||||
}
|
||||
var item3 = {
|
||||
icon: './././imgs/ic_secure.png',
|
||||
title: '安全',
|
||||
desc: '消息通道和消息内容全程加密,防中间人攻击和串改消息内容'
|
||||
}
|
||||
|
||||
var item4 = {
|
||||
icon: './././imgs/ic_function.png',
|
||||
title: '功能强劲',
|
||||
desc: 'MAC 笔记本单机测试 16w 多/秒的消息(包含存储)吞吐量,频道支持万人同时订阅'
|
||||
}
|
||||
|
||||
var item5 = {
|
||||
icon: './././imgs/ic_extend.png',
|
||||
title: '扩展性强',
|
||||
desc: '采用频道设计理念,目前支持群组频道,点对点频道,后续可以根据自己业务自定义频道可实现机器人频道,客服频道等等'
|
||||
}
|
||||
|
||||
var item6 = {
|
||||
icon: './././imgs/ic_compatibility.png',
|
||||
title: '兼容性强',
|
||||
desc: '同时无差别支持 tcp,websocket'
|
||||
}
|
||||
var list1 = []
|
||||
var list2 = []
|
||||
var list3 = []
|
||||
|
||||
list1.push(item1)
|
||||
list1.push(item2)
|
||||
if (!isPhone) {
|
||||
list1.push(item3)
|
||||
list2.push(item4)
|
||||
list2.push(item5)
|
||||
list2.push(item6)
|
||||
} else {
|
||||
list2.push(item3)
|
||||
list2.push(item4)
|
||||
list3.push(item5)
|
||||
list3.push(item6)
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="home-page">
|
||||
<div className="banner">
|
||||
|
||||
<div className={`content ${color}`} style={{ backgroundImage: 'url(./././imgs/ic_bg.png)' }}>
|
||||
|
||||
<label className="center-title">悟空IM</label>
|
||||
<label className="center-small-text">让信息传递更简单</label>
|
||||
<div className={`btn-view ${color}`}>
|
||||
<a href="/guide/guide" className="btn">立即上手</a>
|
||||
<a style={{ marginLeft: '30px' }} target="_blank" href="https://github.com/WuKongIM/WuKongIM"
|
||||
className="btn">Github</a>
|
||||
</div>
|
||||
<p className="content-text">悟空IM是高性能通用即时通讯服务,支持聊天应用,消息推送,物联网通讯,音视频信令,直播弹幕,客服系统,AI 通讯,即时社区等场景。</p>
|
||||
</div>
|
||||
|
||||
<div className="des">
|
||||
<div className={`card ${color}`}>
|
||||
<div className='bg'>
|
||||
<label className="big-font">特性</label>
|
||||
<div style={{ marginTop: '37px', display: 'flex' }}>
|
||||
{
|
||||
list1.map((item: any) =>
|
||||
<div className='card-item' style={{ width: isPhone ? '50%' : '33.3%' }}>
|
||||
<img className="img" src={item.icon} />
|
||||
<label className="characteristic-title">{item.title}</label>
|
||||
<label className="characteristic-content">{item.desc}</label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div style={{ display: 'flex' }}>
|
||||
{
|
||||
list2.map((item: any) =>
|
||||
<div className='card-item' style={{ width: isPhone ? '50%' : '33.3%' }}>
|
||||
<img className="img" src={item.icon} />
|
||||
<label className="characteristic-title">{item.title}</label>
|
||||
<label className="characteristic-content">{item.desc}</label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div style={{ display: 'flex' }} >
|
||||
{
|
||||
list3.map((item: any) =>
|
||||
<div className='card-item' style={{ width: isPhone ? '50%' : '33.3%' }}>
|
||||
<img className="img" src={item.icon} />
|
||||
<label className="characteristic-title">{item.title}</label>
|
||||
<label className="characteristic-content">{item.desc}</label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
@ -1,212 +0,0 @@
|
||||
[home="true"] {
|
||||
.dumi-default-doc-layout>main {
|
||||
padding: 0px;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
.dumi-default-header {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.dumi-default-navbar li a {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.dumi-default-logo {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.dumi-default-search-bar input {
|
||||
background-color: white !important;
|
||||
border: 1px solid #d9d9d9 !important;
|
||||
}
|
||||
|
||||
.dumi-default-search-shortcut {
|
||||
border: 1px solid #d9d9d9 !important;
|
||||
}
|
||||
|
||||
.dumi-default-search-bar input::placeholder {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.dumi-default-color-switch svg {
|
||||
color: white;
|
||||
}
|
||||
.dumi-default-color-switch svg path{
|
||||
fill: white;
|
||||
}
|
||||
|
||||
.dumi-default-icon svg {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.dumi-default-icon svg path{
|
||||
fill: white;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.home-page {
|
||||
font-size: 14px;
|
||||
margin-top: -76px;
|
||||
color: white;
|
||||
|
||||
.banner {
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
// position: absolute;
|
||||
// top: 0px;
|
||||
// right: 0px;
|
||||
// width: 100%;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
list-style: none;
|
||||
background-color: transparent;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.center-title {
|
||||
font-weight: bold;
|
||||
font-size: 100px;
|
||||
margin-top: 8rem;
|
||||
display: block;
|
||||
align-content: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.center-small-text {
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.des {
|
||||
margin-top: -5rem;
|
||||
position: inherit;
|
||||
text-align: center;
|
||||
margin-left: 10%;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flow-root;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background-repeat: repeat;
|
||||
background-position: 50%;
|
||||
|
||||
.content-text {
|
||||
font-size: 14px;
|
||||
margin-top: 5rem;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
margin-left: 30%;
|
||||
color: white;
|
||||
margin-right: 30%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-view {
|
||||
margin-top: 50px;
|
||||
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
-moz-border-radius: 4px;
|
||||
/*Gecko(Firefox内核)浏览器圆角样式*/
|
||||
-webkit-border-radius: 30px;
|
||||
/*webkit(Chrome内核)浏览器圆角样式*/
|
||||
border-radius: 30px;
|
||||
/*Trident(IE内核)浏览器圆角样式*/
|
||||
color: #df5d2a !important;
|
||||
background: #fff;
|
||||
padding: 8px 18px 8px 18px !important;
|
||||
border: 1px solid #df5d2a;
|
||||
}
|
||||
|
||||
// &.dark {
|
||||
// .btn {
|
||||
// color: #9f4522 !important;
|
||||
// background: #141414;
|
||||
// border: 1px solid #9f4522;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
.card {
|
||||
.bg {
|
||||
background: #fff !important;
|
||||
box-shadow: 0px 0px 100px 1PX #f8f8f7;
|
||||
}
|
||||
|
||||
.card-item {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
width: 33.33%;
|
||||
margin-right: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
.big-font {
|
||||
display: block;
|
||||
padding-top: 40px;
|
||||
font-size: 30px;
|
||||
font-family: PingFangSC-Semibold, PingFang SC;
|
||||
font-weight: 600;
|
||||
color: #000000;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
.characteristic-title {
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Semibold, PingFang SC;
|
||||
font-weight: 600;
|
||||
margin-top: 10px;
|
||||
color: #333333;
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
|
||||
.characteristic-content {
|
||||
font-size: 12px;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
line-height: 17px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
&.dark {
|
||||
.bg {
|
||||
background: #0a0909 !important;
|
||||
box-shadow: 0px 0px 100px 1PX #282828;
|
||||
}
|
||||
|
||||
.big-font {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.characteristic-title {
|
||||
color: #d1d0d0;
|
||||
}
|
||||
|
||||
.characteristic-content {
|
||||
color: #8590a0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
.dumirc.ts
@ -1,14 +0,0 @@
|
||||
import { defineConfig } from 'dumi';
|
||||
|
||||
export default defineConfig({
|
||||
themeConfig: {
|
||||
logo: '/logo.png',
|
||||
name: '悟空IM',
|
||||
hd: { rules: [] },
|
||||
socialLinks: {
|
||||
github: 'https://github.com/WuKongIM/WuKongIM',
|
||||
},
|
||||
footer: "Copyright © 2023 | Powered by 悟空IM | <a href='https://beian.miit.gov.cn/' style='color:gray'>ICP备案号:沪ICP备2021032718号-2</a>",
|
||||
},
|
||||
headScripts: ["https://hm.baidu.com/hm.js?219604efa41d5fcab346766087ead60a"] // 百度统计
|
||||
});
|
@ -1,13 +1,15 @@
|
||||
# http://editorconfig.org
|
||||
# @see: http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
[*] # 表示所有文件适用
|
||||
charset = utf-8 # 设置文件字符集为 utf-8
|
||||
end_of_line = lf # 控制换行类型(lf | cr | crlf)
|
||||
insert_final_newline = true # 始终在文件末尾插入一个新行
|
||||
indent_style = tab # 缩进风格(tab | space)
|
||||
indent_size = 2 # 缩进大小
|
||||
max_line_length = 130 # 最大行长度
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
[*.md] # 表示仅 md 文件适用以下规则
|
||||
max_line_length = off # 关闭最大行长度限制
|
||||
trim_trailing_whitespace = false # 关闭末尾空格修剪
|
29
.gitignore
vendored
@ -1,5 +1,28 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
/dist
|
||||
.dumi/tmp
|
||||
.dumi/tmp-production
|
||||
dist
|
||||
dist-ssr
|
||||
stats.html
|
||||
*.local
|
||||
docs/.vitepress/cache
|
||||
.vitepress/cache
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
!.vscode/settings.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx commitlint --edit "${1}"
|
@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
@ -1,3 +0,0 @@
|
||||
.dumi/tmp
|
||||
.dumi/tmp-production
|
||||
*.yaml
|
@ -1,14 +0,0 @@
|
||||
module.exports = {
|
||||
printWidth: 80,
|
||||
proseWrap: 'never',
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
overrides: [
|
||||
{
|
||||
files: '*.md',
|
||||
options: {
|
||||
proseWrap: 'preserve',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
71
.vitepress/config.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import { defineConfig } from "vitepress";
|
||||
import mdItCustomAttrs from "markdown-it-custom-attrs";
|
||||
|
||||
import UnoCSS from "unocss/vite";
|
||||
|
||||
import { navbar } from "./navbar";
|
||||
import { sidebar } from "./sidebar";
|
||||
|
||||
export default defineConfig({
|
||||
title: "悟空IM",
|
||||
description: "IM",
|
||||
lang: "zh-CN",
|
||||
head: [
|
||||
["meta", { name: "keywords", content: "IM" }],
|
||||
["link", { rel: "icon", type: "image/x-icon", href: "/favicon.ico" }],
|
||||
["link", { rel: "stylesheet", href: "/css/fancybox.css" }],
|
||||
["script", { src: "/js/fancybox.umd.js" }],
|
||||
["script", { src: "https://hm.baidu.com/hm.js?219604efa41d5fcab346766087ead60a" }], // 百度统计
|
||||
],
|
||||
markdown: {
|
||||
theme: {
|
||||
light: "vitesse-light",
|
||||
dark: "vitesse-dark",
|
||||
},
|
||||
config: (md) => md.use(mdItCustomAttrs, "image", { "data-fancybox": "gallery" }),
|
||||
},
|
||||
lastUpdated: true,
|
||||
srcDir: "./src",
|
||||
themeConfig: {
|
||||
logo: "/logo.png",
|
||||
siteTitle: "悟空IM",
|
||||
nav: navbar,
|
||||
sidebar: sidebar,
|
||||
lastUpdatedText: "上次更新",
|
||||
outlineTitle: "目录",
|
||||
outline: [2, 6],
|
||||
docFooter: {
|
||||
prev: "上一篇",
|
||||
next: "下一篇",
|
||||
},
|
||||
socialLinks: [
|
||||
{ icon: 'github', link: 'https://github.com/WuKongIM/WuKongIM' }
|
||||
],
|
||||
footer: {
|
||||
message: `本文档内容版权属于 悟空IM 作者,保留所有权利`,
|
||||
copyright: "Copyright © 2023 | Powered by 悟空IM | ICP备案号:沪ICP备2021032718号-2",
|
||||
},
|
||||
search: {
|
||||
provider: "local",
|
||||
options: {
|
||||
translations: {
|
||||
button: { buttonText: "搜索文档", buttonAriaLabel: "搜索文档" },
|
||||
modal: {
|
||||
noResultsText: "无法找到相关结果",
|
||||
resetButtonTitle: "清除查询条件",
|
||||
footer: { selectText: "选择", navigateText: "切换", closeText: "关闭" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
vite: {
|
||||
optimizeDeps: {
|
||||
exclude: ["vitepress"],
|
||||
},
|
||||
server: {
|
||||
host: "0.0.0.0",
|
||||
},
|
||||
plugins: [UnoCSS()],
|
||||
},
|
||||
});
|
27
.vitepress/navbar.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { DefaultTheme } from "vitepress/types/default-theme";
|
||||
|
||||
export const navbar: DefaultTheme.NavItem[] = [
|
||||
{
|
||||
text: " 指南",
|
||||
link: "/guide/guide",
|
||||
activeMatch: "^/guide",
|
||||
},
|
||||
{
|
||||
text: "API文档",
|
||||
link: "/api/",
|
||||
activeMatch: "^/api",
|
||||
},
|
||||
{
|
||||
text: "SDK文档",
|
||||
link: "/sdk/",
|
||||
activeMatch: "^/sdk",
|
||||
},
|
||||
{
|
||||
text: "相关链接",
|
||||
activeMatch: "^/im",
|
||||
items: [
|
||||
{ text: "Go", link: "https://pkg.go.dev/" },
|
||||
{ text: "Node", link: "https://nodejs.org/" },
|
||||
],
|
||||
},
|
||||
];
|
61
.vitepress/sidebar.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { DefaultTheme } from "vitepress";
|
||||
|
||||
export const sidebar: DefaultTheme.Sidebar = {
|
||||
"/guide": [
|
||||
{
|
||||
text: "介绍",
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: "文档阅读引导", link: "/guide/guide" },
|
||||
{ text: "什么是悟空 IM", link: "/guide/" },
|
||||
{ text: "基础概念", link: "/guide/initialize" },
|
||||
{ text: "适用场景", link: "/guide/scene" },
|
||||
{ text: "Demo 演示", link: "/guide/demo" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "快速开始",
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: "部署", link: "/guide/quickstart" },
|
||||
{ text: "集成到自己系统", link: "/guide/integration" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "进阶",
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: "配置说明", link: "/guide/fullconfig" },
|
||||
{ text: "WSS 配置", link: "/guide/wss" },
|
||||
{ text: "命令行工具", link: "/guide/cli" },
|
||||
{ text: "测试", link: "/guide/stress" },
|
||||
{ text: "悟空 IM 协议", link: "/guide/proto" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "其他",
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: "常见问题", link: "/guide/others" },
|
||||
],
|
||||
}
|
||||
],
|
||||
"/api": [
|
||||
{ text: "基础", link: "/api/" },
|
||||
{ text: "用户", link: "/api/user" },
|
||||
{ text: "频道", link: "/api/channel" },
|
||||
{ text: "消息", link: "/api/message" },
|
||||
{ text: "最近会话", link: "/api/conversation" },
|
||||
{ text: "Webhook", link: "/api/webhook" },
|
||||
{ text: "Datasource", link: "/api/datasource" },
|
||||
],
|
||||
"/sdk": [
|
||||
{ text: "概述", link: "/sdk/" },
|
||||
{ text: "IOS", link: "/sdk/ios" },
|
||||
{ text: "Android", link: "/sdk/android" },
|
||||
{ text: "Javascript", link: "/sdk/javascript" },
|
||||
{ text: "Uniapp", link: "/sdk/uniapp" },
|
||||
{ text: "Flutter", link: "/sdk/flutter" },
|
||||
{ text: "c", link: "/sdk/c" },
|
||||
]
|
||||
};
|
89
.vitepress/theme/components/HomePreview.vue
Normal file
@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div class="home-preview-block">
|
||||
<div class="home-preview">
|
||||
<h2>截图预览</h2>
|
||||
<div class="items">
|
||||
<div class="item">
|
||||
<img data-fancybox="gallery" src="/imgs/screen1.png" />
|
||||
</div>
|
||||
<div class="item">
|
||||
<img data-fancybox="gallery" src="/imgs/screen2.png" />
|
||||
</div>
|
||||
<div class="item">
|
||||
<img data-fancybox="gallery" src="/imgs/screen3.png" />
|
||||
</div>
|
||||
<div class="item">
|
||||
<img data-fancybox="gallery" src="/imgs/screen4.png" />
|
||||
</div>
|
||||
<div class="item">
|
||||
<img data-fancybox="gallery" src="/imgs/screen5.png" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.home-preview-block {
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.home-preview {
|
||||
max-width: 1152px;
|
||||
margin: 50px auto 0;
|
||||
}
|
||||
|
||||
.home-preview h2 {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.home-preview .items {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: -8px;
|
||||
}
|
||||
|
||||
.home-preview .items .item {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.home-preview .items .item img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.home-preview .items .item p {
|
||||
padding: 24px;
|
||||
border-radius: 12px;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
}
|
||||
|
||||
.home-preview .items .item p :deep(img) {
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.home-preview-block {
|
||||
padding: 0 48px;
|
||||
}
|
||||
|
||||
.home-preview .items .item {
|
||||
width: calc(100% / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.home-preview-block {
|
||||
padding: 0 64px;
|
||||
}
|
||||
|
||||
.home-preview .items .item {
|
||||
width: calc(100% / 3);
|
||||
}
|
||||
}
|
||||
</style>
|
16
.vitepress/theme/index.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { h } from "vue";
|
||||
import Theme from "vitepress/theme";
|
||||
import "./styles/var.css";
|
||||
import "./styles/custom.css";
|
||||
import 'uno.css';
|
||||
|
||||
import HomePreview from "./components/HomePreview.vue";
|
||||
|
||||
export default {
|
||||
...Theme,
|
||||
Layout() {
|
||||
return h(Theme.Layout, null, {
|
||||
"home-features-after": () => h(HomePreview),
|
||||
});
|
||||
},
|
||||
};
|
10
.vitepress/theme/styles/custom.css
Normal file
@ -0,0 +1,10 @@
|
||||
.docs-cn-github-release-tag {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
padding: 4px 6px;
|
||||
margin-left: 6px;
|
||||
background: var(--vp-button-brand-bg);
|
||||
color: white;
|
||||
border-radius: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
112
.vitepress/theme/styles/var.css
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Colors
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
--vp-c-brand: #df5d2a;
|
||||
--vp-c-brand-light: #df5d2a;
|
||||
--vp-c-brand-lighter: #ff9a2e;
|
||||
--vp-c-brand-lightest: #ff7d00;
|
||||
--vp-c-brand-dark: #483838;
|
||||
--vp-c-brand-darker: #3a2d2d;
|
||||
--vp-c-brand-dimm: rgba(100, 108, 255, 0.08);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component: Button
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
--vp-button-brand-border: var(--vp-c-brand-light);
|
||||
--vp-button-brand-text: var(--vp-c-text-dark-1);
|
||||
--vp-button-brand-bg: var(--vp-c-brand);
|
||||
--vp-button-brand-hover-border: var(--vp-c-brand-light);
|
||||
--vp-button-brand-hover-text: var(--vp-c-text-dark-1);
|
||||
--vp-button-brand-hover-bg: var(--vp-c-brand-light);
|
||||
--vp-button-brand-active-border: var(--vp-c-brand-light);
|
||||
--vp-button-brand-active-text: var(--vp-c-text-dark-1);
|
||||
--vp-button-brand-active-bg: var(--vp-button-brand-bg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component: Home
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
--vp-home-hero-name-color: transparent;
|
||||
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #ffcf8b 10%, var(--vp-c-brand-lightest));
|
||||
|
||||
--vp-home-hero-image-background-image: linear-gradient(-45deg, var(--vp-c-brand-lightest) 90%, #ffcf8b 10%);
|
||||
--vp-home-hero-image-filter: blur(40px);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
:root {
|
||||
--vp-home-hero-image-filter: blur(56px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
:root {
|
||||
--vp-home-hero-image-filter: blur(72px);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Component: Custom Block
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
:root {
|
||||
--vp-custom-block-tip-border: var(--vp-c-brand);
|
||||
--vp-custom-block-tip-text: var(--vp-c-brand-darker);
|
||||
--vp-custom-block-tip-bg: var(--vp-c-brand-dimm);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--vp-custom-block-tip-border: var(--vp-c-brand);
|
||||
--vp-custom-block-tip-text: var(--vp-c-brand-lightest);
|
||||
--vp-custom-block-tip-bg: var(--vp-c-brand-dimm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component: Algolia
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
.DocSearch {
|
||||
--docsearch-primary-color: var(--vp-c-brand-light) !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* VitePress: Custom fix
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
Use lighter colors for links in dark mode for a11y.
|
||||
Also specify some classes twice to have higher specificity
|
||||
over scoped class data attribute.
|
||||
*/
|
||||
.dark .vp-doc a,
|
||||
.dark .vp-doc a > code,
|
||||
.dark .VPNavBarMenuLink.VPNavBarMenuLink:hover,
|
||||
.dark .VPNavBarMenuLink.VPNavBarMenuLink.active,
|
||||
.dark .link.link:hover,
|
||||
.dark .link.link.active,
|
||||
.dark .edit-link-button.edit-link-button,
|
||||
.dark .pager-link .title {
|
||||
color: var(--vp-c-brand-lighter);
|
||||
}
|
||||
|
||||
.dark .vp-doc a:hover,
|
||||
.dark .vp-doc a > code:hover {
|
||||
color: var(--vp-c-brand-lightest);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Transition by color instead of opacity */
|
||||
.dark .vp-doc .custom-block a {
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
body {
|
||||
cursor: url('/blue.cur'), auto;
|
||||
}
|
8
.vitepress/utils/fetchReleaseTag.js
Normal file
@ -0,0 +1,8 @@
|
||||
export function fetchReleaseTag() {
|
||||
const releaseTag = "1.0.0";
|
||||
const tagLineParagragh = document.querySelector("div.VPHero.has-image.VPHomeHero > div > div.main > p.tagline");
|
||||
const docsReleaseTagSpan = document.createElement("samp");
|
||||
docsReleaseTagSpan.classList.add("docs-cn-github-release-tag");
|
||||
docsReleaseTagSpan.innerText = releaseTag;
|
||||
tagLineParagragh?.appendChild(docsReleaseTagSpan);
|
||||
}
|
18
Dockerfile
@ -1,18 +0,0 @@
|
||||
FROM node:18.0.0 as builder
|
||||
WORKDIR /app
|
||||
RUN curl -o- -L https://yarnpkg.com/install.sh | bash
|
||||
COPY package.json .
|
||||
COPY yarn.lock .
|
||||
# https://registry.npmjs.org/ https://registry.npm.taobao.org
|
||||
# RUN yarn config set registry https://registry.npm.taobao.org -g
|
||||
# RUN yarn config set disturl https://npm.taobao.org/dist
|
||||
RUN yarn install
|
||||
COPY . .
|
||||
RUN yarn build
|
||||
|
||||
FROM nginx:latest
|
||||
COPY --from=builder /app/docker-entrypoint.sh /docker-entrypoint2.sh
|
||||
COPY --from=builder /app/nginx.conf.template /
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
ENTRYPOINT ["sh", "/docker-entrypoint2.sh"]
|
||||
CMD ["nginx","-g","daemon off;"]
|
6
Makefile
@ -1,6 +0,0 @@
|
||||
build:
|
||||
docker build -t wukongimdocs .
|
||||
deploy:
|
||||
docker build -t wukongimdocs .
|
||||
docker tag wukongimdocs wukongim/wukongimdocs:latest
|
||||
docker push wukongim/wukongimdocs:latest
|
29
README.md
@ -1,20 +1,19 @@
|
||||
# WuKongIMDocs
|
||||
# 悟空IM
|
||||
|
||||
A static site base on [dumi](https://d.umijs.org).
|
||||
## 本地开发
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# install dependencies
|
||||
$ yarn install
|
||||
|
||||
# start dev server
|
||||
$ yarn start
|
||||
|
||||
# build docs
|
||||
$ yarn run build
|
||||
``` sh
|
||||
pnpm run dev
|
||||
```
|
||||
|
||||
## LICENSE
|
||||
## 编译
|
||||
|
||||
MIT
|
||||
``` sh
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
## 预览
|
||||
|
||||
``` sh
|
||||
pnpm run serve
|
||||
```
|
||||
|
BIN
WKJSSDK.xmind
BIN
WKiOSSDK.xmind
@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -eu
|
||||
|
||||
envsubst '${API_URL}' < /nginx.conf.template > /etc/nginx/conf.d/default.conf
|
||||
|
||||
|
||||
exec "$@"
|
@ -1,26 +0,0 @@
|
||||
<!-- ---
|
||||
title: 悟空IM
|
||||
hero:
|
||||
title: 悟空IM
|
||||
description: 让信息传递更简单
|
||||
actions:
|
||||
- text: 立即上手
|
||||
link: /guide/guide
|
||||
- text: Github
|
||||
link: https://github.com/WuKongIM/WuKongIM
|
||||
# features:
|
||||
# - title: Hello
|
||||
# emoji: 💎
|
||||
# description: Put hello description here
|
||||
# - title: World
|
||||
# emoji: 🌈
|
||||
# description: Put world description here
|
||||
# - title: '!'
|
||||
# emoji: 🚀
|
||||
# description: Put ! description here
|
||||
# - title: 'zz'
|
||||
# emoji: 🚀
|
||||
# description: Put ! description here
|
||||
footer: Open-source Apache 2.0 Licensed | Copyright © 2020<br />Powered by 上海信必达网络科技
|
||||
--- -->
|
||||
<!-- <embed src="./index.html"></embed> -->
|
Before Width: | Height: | Size: 225 KiB |
@ -1,10 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
63
package.json
@ -1,36 +1,43 @@
|
||||
{
|
||||
"name": "WuKongIMDocs",
|
||||
"version": "0.0.1",
|
||||
"description": "Docs For WuKongIM",
|
||||
"license": "MIT",
|
||||
"name": "wukongim-doc",
|
||||
"version": "1.0.0",
|
||||
"description": "wukongim文档",
|
||||
"keywords": [
|
||||
"悟空IM",
|
||||
"IM"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "dumi build",
|
||||
"dev": "dumi dev",
|
||||
"prepare": "husky install && dumi setup",
|
||||
"start": "npm run dev"
|
||||
},
|
||||
"commitlint": {
|
||||
"extends": [
|
||||
"@commitlint/config-conventional"
|
||||
]
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{md,json}": [
|
||||
"prettier --write --no-error-on-unmatched-pattern"
|
||||
]
|
||||
"dev": "vitepress dev",
|
||||
"build": "vitepress build",
|
||||
"serve": "vitepress serve"
|
||||
},
|
||||
"dependencies": {
|
||||
"prism-react-renderer": "^2.0.5"
|
||||
"@iconify-json/carbon": "^1.1.18",
|
||||
"@iconify-json/logos": "^1.1.33",
|
||||
"@iconify-json/mdi": "^1.1.52",
|
||||
"@iconify-json/ph": "^1.1.5",
|
||||
"@iconify-json/twemoji": "^1.1.11",
|
||||
"@iconify-json/vscode-icons": "^1.1.25",
|
||||
"vitepress": "1.0.0-beta.3",
|
||||
"vue": "^3.3.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.1.2",
|
||||
"@commitlint/config-conventional": "^17.1.0",
|
||||
"dumi": "^2.1.22",
|
||||
"husky": "^8.0.1",
|
||||
"lint-staged": "^13.0.3",
|
||||
"prettier": "^2.7.1"
|
||||
"@types/node": "^18.15.13",
|
||||
"markdown-it-custom-attrs": "^1.0.2",
|
||||
"typescript": "^5.0.4",
|
||||
"unocss": "^0.53.3",
|
||||
"vite": "^4.3.9"
|
||||
},
|
||||
"authors": [
|
||||
"tt@gmail.com"
|
||||
]
|
||||
"pnpm": {
|
||||
"peerDependencyRules": {
|
||||
"ignoreMissing": [
|
||||
"@algolia/client-search"
|
||||
]
|
||||
}
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"packageManager": "pnpm@7.9.5",
|
||||
"license": "ISC"
|
||||
}
|
||||
|
1704
pnpm-lock.yaml
generated
Normal file
Before Width: | Height: | Size: 2.2 KiB |
@ -1,11 +1,3 @@
|
||||
---
|
||||
group:
|
||||
title: 进阶
|
||||
order: 300
|
||||
order: 300
|
||||
title: 命令行工具
|
||||
---
|
||||
|
||||
# 命令行工具
|
||||
|
||||
## 安装命令行工具
|
@ -1,11 +1,3 @@
|
||||
---
|
||||
group:
|
||||
title: 介绍
|
||||
order: -1
|
||||
order: 300
|
||||
title: Demo演示
|
||||
---
|
||||
|
||||
# Demo 演示
|
||||
|
||||
## 前端聊天 Demo
|
@ -1,11 +1,3 @@
|
||||
---
|
||||
title: 配置说明
|
||||
group:
|
||||
title: 进阶
|
||||
order: 100
|
||||
order: 200
|
||||
---
|
||||
|
||||
# 配置说明
|
||||
|
||||
## 配置文件
|
@ -1,9 +1,6 @@
|
||||
---
|
||||
group:
|
||||
title: 介绍
|
||||
order: -1
|
||||
order: -1
|
||||
title: 文档阅读引导
|
||||
title: 介绍
|
||||
---
|
||||
|
||||
# 文档阅读引导
|
@ -1,14 +1,3 @@
|
||||
---
|
||||
group:
|
||||
title: 介绍
|
||||
order: -1
|
||||
order: 1
|
||||
title: 什么是悟空IM
|
||||
nav:
|
||||
title: 指南
|
||||
order: -1
|
||||
---
|
||||
|
||||
# 什么是悟空 IM
|
||||
|
||||
高性能通用即时通讯服务,支持聊天应用,消息推送,物联网通讯,音视频信令,直播弹幕,客服系统,AI 通讯,即时社区等场景。
|
@ -1,11 +1,3 @@
|
||||
---
|
||||
group:
|
||||
title: 介绍
|
||||
order: -1
|
||||
order: 1
|
||||
title: 基础概念
|
||||
---
|
||||
|
||||
# 基础概念
|
||||
|
||||
### 频道
|
@ -1,11 +1,3 @@
|
||||
---
|
||||
group:
|
||||
title: 快速开始
|
||||
order: -1
|
||||
order: 200
|
||||
title: 集成到自己系统
|
||||
---
|
||||
|
||||
# 集成到自己系统
|
||||
|
||||
`所有悟空IM的接口不要直接给APP端调用,应该前端先调用自己的业务API,业务API再调用悟空IM的API,并且悟空IM的API不要暴露给外网,这样可以保证数据的安全性。`
|
@ -1,11 +1,3 @@
|
||||
---
|
||||
title: 常见问题
|
||||
group:
|
||||
title: 其他
|
||||
order: 100
|
||||
order: 100
|
||||
---
|
||||
|
||||
# 常见问题
|
||||
|
||||
#### iOS 打包失败 file not found: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a
|
@ -1,11 +1,3 @@
|
||||
---
|
||||
group:
|
||||
title: 进阶
|
||||
order: 300
|
||||
order: 700
|
||||
title: 悟空IM协议
|
||||
---
|
||||
|
||||
# 悟空 IM 协议
|
||||
|
||||
## 控制报文结构
|
@ -1,11 +1,3 @@
|
||||
---
|
||||
title: 部署
|
||||
group:
|
||||
title: 快速开始
|
||||
order: -1
|
||||
order: 100
|
||||
---
|
||||
|
||||
# 部署
|
||||
|
||||
## 一键部署(推荐)
|
@ -1,12 +1,6 @@
|
||||
---
|
||||
group:
|
||||
title: 介绍
|
||||
order: -1
|
||||
order: 1
|
||||
title: 适用场景
|
||||
---
|
||||
# 适用场景
|
||||
|
||||
### 即时通讯
|
||||
## 即时通讯
|
||||
|
||||
- 群频道支持
|
||||
- 个人频道支持
|
||||
@ -14,13 +8,13 @@ title: 适用场景
|
||||
- 离线消息推送支持
|
||||
- 最近会话维护
|
||||
|
||||
### 消息推送/站内消息
|
||||
## 消息推送/站内消息
|
||||
|
||||
- 群频道支持
|
||||
- 个人频道支持
|
||||
- 离线消息推送支持
|
||||
|
||||
### 客服系统
|
||||
## 客服系统
|
||||
|
||||
- 客服频道支持
|
||||
|
||||
@ -28,17 +22,17 @@ title: 适用场景
|
||||
|
||||
- 第三方服务器可决定分配指定的订阅者成组投递
|
||||
|
||||
### 游戏聊天室
|
||||
## 游戏聊天室
|
||||
|
||||
- 大群频道支持
|
||||
|
||||
<!-- 把联机的用户建立一个频道内,当A打了敌人后,A将数据告诉你们自己的业务服务器,业务服务器处理后调用悟空IM的发送消息接口,发送消息的频道参数指定为这个建立的频道,这样这个频道内所有人都能收到包括A -->
|
||||
|
||||
### 音视频信令服务器
|
||||
## 音视频信令服务器
|
||||
|
||||
- 支持临时指令消息投递
|
||||
|
||||
### 直播弹幕
|
||||
## 直播弹幕
|
||||
|
||||
- 临时消息投递
|
||||
|
||||
@ -46,16 +40,16 @@ title: 适用场景
|
||||
|
||||
一个直播一个频道,用户进入直播就是用户订阅频道,用户退出直播就是用户取消订阅频道,直播结束就是频道销毁。
|
||||
|
||||
### 实时 AI 反馈
|
||||
## 实时 AI 反馈
|
||||
|
||||
- 支持客户端发的消息推送给第三方服务器,第三方服务器反馈给 AI 后返回的结果再推送给客户端
|
||||
|
||||
### 即时社区
|
||||
## 即时社区
|
||||
|
||||
- 社区频道支持
|
||||
- 支持 topic 模式的消息投递
|
||||
|
||||
### 物联网通讯
|
||||
## 物联网通讯
|
||||
|
||||
- mqtt 协议支持(待开发)
|
||||
- 支持发布与订阅
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 213 KiB |
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 242 KiB |
Before Width: | Height: | Size: 463 KiB After Width: | Height: | Size: 463 KiB |
Before Width: | Height: | Size: 211 KiB After Width: | Height: | Size: 211 KiB |
Before Width: | Height: | Size: 406 KiB After Width: | Height: | Size: 406 KiB |
Before Width: | Height: | Size: 578 KiB After Width: | Height: | Size: 578 KiB |
Before Width: | Height: | Size: 563 KiB After Width: | Height: | Size: 563 KiB |
@ -1,11 +1,3 @@
|
||||
---
|
||||
group:
|
||||
title: 进阶
|
||||
order: 300
|
||||
order: 600
|
||||
title: 测试
|
||||
---
|
||||
|
||||
# 测试
|
||||
|
||||
## 性能测试
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 182 KiB |
@ -1,10 +1,3 @@
|
||||
---
|
||||
group:
|
||||
title: 进阶
|
||||
order: 290
|
||||
title: WSS配置
|
||||
---
|
||||
|
||||
# WSS 配置
|
||||
|
||||
```yaml
|
Before Width: | Height: | Size: 195 KiB After Width: | Height: | Size: 195 KiB |
50
src/index.md
Normal file
@ -0,0 +1,50 @@
|
||||
---
|
||||
layout: home
|
||||
|
||||
title: 悟空IM
|
||||
titleTemplate: 悟空IM
|
||||
|
||||
hero:
|
||||
name: 悟空IM
|
||||
text: 让信息传递更简单
|
||||
tagline: 悟空IM是高性能通用即时通讯服务,支持聊天应用,消息推送,物联网通讯,音视频信令,直播弹幕,客服系统,AI 通讯,即时社区等场景
|
||||
image:
|
||||
src: /logo_white.png
|
||||
alt: logo
|
||||
actions:
|
||||
- theme: brand
|
||||
text: 马上开始
|
||||
link: /guide/guide
|
||||
- theme: alt
|
||||
text: 介绍
|
||||
link: /guide/
|
||||
|
||||
features:
|
||||
- icon: <span class="i-carbon:ibm-cloud-pak-integration"></span>
|
||||
title: 零依赖
|
||||
details: 没有依赖任何第三方组件,部署简单,一条命令即可启动
|
||||
- icon: <span class="i-carbon:plug"></span>
|
||||
title: 完全自研
|
||||
details: 自研消息数据库,消息分区永久存储,自研二进制协议,支持自定义协议
|
||||
- icon: <span class="i-carbon:ibm-cloud-hyper-protect-crypto-services"></span>
|
||||
title: 安全
|
||||
details: 消息通道和消息内容全程加密,防中间人攻击和串改消息内容
|
||||
- icon: <span class="i-carbon:ibm-cloud-pak-manta-automated-data-lineage"></span>
|
||||
title: 功能强劲
|
||||
details: MAC 笔记本单机测试 16w 多/秒的消息(包含存储)吞吐量,频道支持万人同时订阅
|
||||
- icon: <span class="i-carbon:deployment-pattern"></span>
|
||||
title: 扩展性强
|
||||
details: 采用频道设计理念,目前支持群组频道,点对点频道,后续可以根据自己业务自定义频道可实现机器人频道,客服频道等等
|
||||
- icon: <span class="i-carbon:api"></span>
|
||||
title: 兼容性强
|
||||
details: 同时无差别支持 tcp,websocket
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from 'vue'
|
||||
import { fetchReleaseTag } from '../.vitepress/utils/fetchReleaseTag.js'
|
||||
|
||||
onMounted(() => {
|
||||
fetchReleaseTag()
|
||||
})
|
||||
</script>
|
BIN
src/public/blue.cur
Normal file
After Width: | Height: | Size: 4.2 KiB |
1
src/public/css/fancybox.css
Normal file
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
BIN
src/public/imgs/screen1.png
Normal file
After Width: | Height: | Size: 463 KiB |
BIN
src/public/imgs/screen2.png
Normal file
After Width: | Height: | Size: 211 KiB |
BIN
src/public/imgs/screen3.png
Normal file
After Width: | Height: | Size: 406 KiB |
BIN
src/public/imgs/screen4.png
Normal file
After Width: | Height: | Size: 578 KiB |
BIN
src/public/imgs/screen5.png
Normal file
After Width: | Height: | Size: 563 KiB |
Before Width: | Height: | Size: 382 KiB After Width: | Height: | Size: 382 KiB |
2
src/public/js/fancybox.umd.js
Normal file
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
BIN
src/public/logo_white.png
Normal file
After Width: | Height: | Size: 18 KiB |
@ -2,6 +2,7 @@
|
||||
title: Android
|
||||
order: 200
|
||||
---
|
||||
# Android
|
||||
|
||||
## 设计理念
|
||||
|
@ -8,13 +8,13 @@ nav:
|
||||
|
||||
# 文档阅读引导
|
||||
|
||||
[iOS SDK](./iOS/index.md)<br/>
|
||||
[iOS SDK](./ios.md)<br/>
|
||||
|
||||
[Android SDK](./Android/index.md) <br/>
|
||||
[Android SDK](./android.md) <br/>
|
||||
|
||||
[JavaScript SDK](./Javascript/index.md) <br/>
|
||||
[JavaScript SDK](./javascript.md) <br/>
|
||||
|
||||
[Uniapp SDK](./uniapp/index.md) <br/>
|
||||
[Uniapp SDK](./uniapp.md) <br/>
|
||||
|
||||
Flutter SDK (待开发)
|
||||
|
@ -1,20 +1,10 @@
|
||||
---
|
||||
order: 1
|
||||
title: iOS
|
||||
nav:
|
||||
title: SDK文档
|
||||
order: 1
|
||||
---
|
||||
|
||||
# iOS
|
||||
|
||||
## 介绍
|
||||
|
||||
### 设计理念
|
||||
## 设计理念
|
||||
|
||||
像设计书的目录一样设计 api, 通过 WKSDK.shared.xxxManager 我们可以访问到所有需要的功能,例如发送消息 `[WKSDK.shared.chatManager sendMessage:xxx]`
|
||||
|
||||
### 结构说明
|
||||
## 结构说明
|
||||
|
||||

|
||||
|
||||
@ -81,7 +71,6 @@ sdk 与已有 APP 交互的整体流程就是 已有 APP 调用 SDK 对应的方
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 集成
|
||||
|
||||
### 通过 CocoaPods 集成
|
||||
@ -89,7 +78,6 @@ sdk 与已有 APP 交互的整体流程就是 已有 APP 调用 SDK 对应的方
|
||||
```objc
|
||||
pod 'WuKongIMSDK'
|
||||
```
|
||||
|
||||
### 通过二进制集成
|
||||
|
||||
(后续完善)
|
||||
@ -109,12 +97,11 @@ pod 'WuKongIMSDK'
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
更多配置请查看 `[WKSDK shared].options`
|
||||
|
||||
## 连接与断开
|
||||
|
||||
#### 数据操作
|
||||
### 数据操作
|
||||
|
||||
```objc
|
||||
// 开始连接
|
||||
@ -125,7 +112,7 @@ pod 'WuKongIMSDK'
|
||||
|
||||
```
|
||||
|
||||
#### 数据监听
|
||||
### 数据监听
|
||||
|
||||
```objc
|
||||
[WKSDK.shared.connectManager addDelegate:self]; // WKConnectionManagerDelegate
|
||||
@ -148,7 +135,7 @@ pod 'WuKongIMSDK'
|
||||
|
||||
## 在线消息收发
|
||||
|
||||
#### 数据操作
|
||||
### 数据操作
|
||||
|
||||
发送消息
|
||||
|
||||
@ -173,7 +160,7 @@ WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
|
||||
[[WKSDK shared].chatManager sendMessage:content channel:channel];
|
||||
```
|
||||
|
||||
#### 数据监听
|
||||
### 数据监听
|
||||
|
||||
```objc
|
||||
[WKSDK.shared.chatManager addDelegate:self]; // WKChatManagerDelegate
|
||||
@ -229,8 +216,6 @@ WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
|
||||
|
||||
...
|
||||
|
||||
@end
|
||||
|
||||
```
|
||||
|
||||
消息正文核心属性
|
||||
@ -243,13 +228,14 @@ WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
|
||||
你自定义的消息类型,在各个平台上需要保持一致
|
||||
@return 正文类型
|
||||
*/
|
||||
+(NSInteger) contentType;
|
||||
|
||||
(NSInteger) contentType;
|
||||
|
||||
// 上层无需实现encode 实现此方法即可
|
||||
-(NSDictionary*) encodeWithJSON;
|
||||
(NSDictionary*) encodeWithJSON;
|
||||
|
||||
// 上层无序实现decode 实现此方法即可
|
||||
-(void) decodeWithJSON:(NSDictionary*)contentDic;
|
||||
(void) decodeWithJSON:(NSDictionary*)contentDic;
|
||||
|
||||
// 消息中的@提醒信息
|
||||
@property (nonatomic, strong) WKMentionedInfo *mentionedInfo;
|
||||
@ -260,8 +246,6 @@ WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
|
||||
|
||||
...
|
||||
|
||||
@end
|
||||
|
||||
```
|
||||
|
||||
## 离线消息接收
|
||||
@ -270,9 +254,9 @@ WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
|
||||
而是采用拉取这 10 个会话的信息和对应的最新 20 条消息,也就是实际只拉取了 200 条消息 相对 100 万条消息来说大大提高了离线拉取速度。用户点进对应的会话才会去按需拉取这个会话的消息。
|
||||
这些机制 SDK 内部都已做好了封装,使用者其实不需要关心。使用者只需要关心最近会话的变化
|
||||
|
||||
最近会话的变化可以通过 WKConversationManager 进行监听
|
||||
最近会话的变化可以通过 **WKConversationManager** 进行监听
|
||||
|
||||
#### 数据操作
|
||||
### 数据操作
|
||||
|
||||
```objc
|
||||
|
||||
@ -311,7 +295,7 @@ WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
|
||||
|
||||
```
|
||||
|
||||
#### 数据监听
|
||||
### 数据监听
|
||||
|
||||
```objc
|
||||
// 添加委托
|
||||
@ -326,7 +310,7 @@ WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
|
||||
@param conversation 最近会话对象
|
||||
@param left 会话剩余数量 UI层可以判断left == 0 的时候才刷新 避免频繁刷新UI导致卡顿
|
||||
*/
|
||||
- (void)onConversationAdd:(WKConversation*)conversation left:(NSInteger)left;
|
||||
(void)onConversationAdd:(WKConversation*)conversation left:(NSInteger)left;
|
||||
|
||||
|
||||
/**
|
||||
@ -335,7 +319,7 @@ WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
|
||||
@param conversation 最近会话对象
|
||||
@param left 会话剩余数量 UI层可以判断left == 0 的时候才刷新 避免频繁刷新UI导致卡顿
|
||||
*/
|
||||
- (void)onConversationUpdate:(WKConversation*)conversation left:(NSInteger)left;
|
||||
(void)onConversationUpdate:(WKConversation*)conversation left:(NSInteger)left;
|
||||
|
||||
/**
|
||||
最近会话未读数发送改变
|
||||
@ -343,15 +327,15 @@ WKTextContent *content = [[WKTextContent alloc] initWithContent:@"hello"];
|
||||
@param channel 频道
|
||||
@param unreadCount 未读数量
|
||||
*/
|
||||
- (void)onConversationUnreadCountUpdate:(WKChannel*)channel unreadCount:(NSInteger)unreadCount;
|
||||
(void)onConversationUnreadCountUpdate:(WKChannel*)channel unreadCount:(NSInteger)unreadCount;
|
||||
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
WKConversation 类的核心属性
|
||||
**WKConversation** 类的核心属性
|
||||
|
||||
```objc
|
||||
``` objc
|
||||
|
||||
/**
|
||||
频道
|
||||
@ -384,11 +368,11 @@ WKConversation 类的核心属性
|
||||
|
||||
@property(nonatomic,copy) NSString *content;
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
## 图片消息
|
||||
|
||||
|
||||
```objc
|
||||
|
||||
@interface WKImageContent : WKMediaMessageContent
|
||||
@ -404,7 +388,7 @@ WKConversation 类的核心属性
|
||||
@param image 原始图片
|
||||
@return 图片消息对象
|
||||
*/
|
||||
+ (instancetype)initWithImage:(UIImage *)image;
|
||||
(instancetype)initWithImage:(UIImage *)image;
|
||||
|
||||
|
||||
|
||||
@ -412,7 +396,7 @@ WKConversation 类的核心属性
|
||||
/// @param data 图片数据
|
||||
/// @param width 图片宽度
|
||||
/// @param height 图片高度
|
||||
+ (instancetype)initWithData:(NSData *)data width:(CGFloat)width height:(CGFloat)height;
|
||||
(instancetype)initWithData:(NSData *)data width:(CGFloat)width height:(CGFloat)height;
|
||||
|
||||
|
||||
/// 初始化
|
||||
@ -420,7 +404,7 @@ WKConversation 类的核心属性
|
||||
/// @param width 原图宽度
|
||||
/// @param height 原图高度
|
||||
/// @param thumbData 缩略图data (如果传了缩略图的data数据,sdk将不再生成缩略图数据)
|
||||
+ (instancetype)initWithData:(NSData *)data width:(CGFloat)width height:(CGFloat)height thumbData:( nullable NSData*)thumbData;
|
||||
(instancetype)initWithData:(NSData *)data width:(CGFloat)width height:(CGFloat)height thumbData:( nullable NSData*)thumbData;
|
||||
|
||||
|
||||
/*!
|
||||
@ -430,7 +414,6 @@ WKConversation 类的核心属性
|
||||
*/
|
||||
@property (nonatomic, getter=isFull) BOOL full;
|
||||
|
||||
@end
|
||||
|
||||
```
|
||||
|
||||
@ -449,7 +432,7 @@ WKConversation 类的核心属性
|
||||
@param waveform 音频波浪数据 (可选参数)
|
||||
@return <#return value description#>
|
||||
*/
|
||||
+ (instancetype)initWithData:(NSData *)voiceData second:(int)second waveform:(NSData*)waveform;
|
||||
(instancetype)initWithData:(NSData *)voiceData second:(int)second waveform:(NSData*)waveform;
|
||||
|
||||
|
||||
// 音频数据
|
||||
@ -460,7 +443,6 @@ WKConversation 类的核心属性
|
||||
// 音频波浪数据 (可选参数)
|
||||
@property(nonatomic,strong) NSData *waveform;
|
||||
|
||||
@end
|
||||
|
||||
```
|
||||
|
||||
@ -475,7 +457,7 @@ WKConversation 类的核心属性
|
||||
/// @param title 位置标题
|
||||
/// @param address 位置地址
|
||||
/// @param image 地图图片
|
||||
+(WKLocationContent*) locationContent:(CGFloat)lng lat:(CGFloat)lat title:(NSString*)title address:(NSString*)address img:(UIImage*)image;
|
||||
(WKLocationContent*) locationContent:(CGFloat)lng lat:(CGFloat)lat title:(NSString*)title address:(NSString*)address img:(UIImage*)image;
|
||||
|
||||
|
||||
|
||||
@ -489,12 +471,7 @@ WKConversation 类的核心属性
|
||||
/// 地图图片
|
||||
@property(nonatomic,strong,readonly) UIImage *mapImage;
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
```
|
||||
|
||||
## CMD 消息
|
||||
|
||||
cmd 消息由服务端下发客户端解析。
|
||||
@ -518,7 +495,6 @@ cmd 消息由服务端下发客户端解析。
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
## 最近会话
|
||||
|
||||
最近会话用于表示会话列表页的数据模型。当用户发送,收取及删除消息时,都会同时去修改最近会话。
|
||||
@ -566,7 +542,7 @@ cmd 消息由服务端下发客户端解析。
|
||||
|
||||
```
|
||||
|
||||
#### 数据操作
|
||||
### 数据操作
|
||||
|
||||
```objc
|
||||
|
||||
@ -585,15 +561,13 @@ cmd 消息由服务端下发客户端解析。
|
||||
|
||||
```
|
||||
|
||||
#### 数据监听
|
||||
### 数据监听
|
||||
|
||||
```objc
|
||||
[[WKSDK shared].conversationManager addDelegate:self] // WKConversationManagerDelegate
|
||||
```
|
||||
|
||||
```objc
|
||||
|
||||
|
||||
// ---------- WKConversationManagerDelegate ----------
|
||||
|
||||
/**
|
||||
@ -602,7 +576,7 @@ cmd 消息由服务端下发客户端解析。
|
||||
@param conversation 最近会话对象
|
||||
@param left 会话剩余数量 UI层可以判断left == 0 的时候才刷新 避免频繁刷新UI导致卡顿
|
||||
*/
|
||||
- (void)onConversationAdd:(WKConversation*)conversation left:(NSInteger)left;
|
||||
(void)onConversationAdd:(WKConversation*)conversation left:(NSInteger)left;
|
||||
|
||||
|
||||
/**
|
||||
@ -611,7 +585,7 @@ cmd 消息由服务端下发客户端解析。
|
||||
@param conversation 最近会话对象
|
||||
@param left 会话剩余数量 UI层可以判断left == 0 的时候才刷新 避免频繁刷新UI导致卡顿
|
||||
*/
|
||||
- (void)onConversationUpdate:(WKConversation*)conversation left:(NSInteger)left;
|
||||
(void)onConversationUpdate:(WKConversation*)conversation left:(NSInteger)left;
|
||||
|
||||
/**
|
||||
最近会话未读数发送改变
|
||||
@ -619,7 +593,7 @@ cmd 消息由服务端下发客户端解析。
|
||||
@param channel 频道
|
||||
@param unreadCount 未读数量
|
||||
*/
|
||||
- (void)onConversationUnreadCountUpdate:(WKChannel*)channel unreadCount:(NSInteger)unreadCount;
|
||||
(void)onConversationUnreadCountUpdate:(WKChannel*)channel unreadCount:(NSInteger)unreadCount;
|
||||
|
||||
...
|
||||
|
||||
@ -693,7 +667,7 @@ cmd 消息由服务端下发客户端解析。
|
||||
|
||||
```
|
||||
|
||||
#### 数据操作
|
||||
### 数据操作
|
||||
|
||||
```objc
|
||||
|
||||
@ -746,15 +720,15 @@ cmd 消息由服务端下发客户端解析。
|
||||
// 实现四个方法 initWithMessage resume cancel suspend
|
||||
@implementation WKFileUploadTask
|
||||
|
||||
- (instancetype)initWithMessage:(WKMessage *)message {
|
||||
self = [super initWithMessage:message];
|
||||
if(self) {
|
||||
[self initTask];
|
||||
}
|
||||
return self;
|
||||
(instancetype)initWithMessage:(WKMessage *)message {
|
||||
self = [super initWithMessage:message];
|
||||
if(self) {
|
||||
[self initTask];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) initTask {
|
||||
(void) initTask {
|
||||
WKMediaContent *mediaContent = (WKMediaContent*)self.message.content;
|
||||
|
||||
NSString *fileLocalPath = mediaContent.localPath; // 附件本地路径
|
||||
@ -776,18 +750,18 @@ cmd 消息由服务端下发客户端解析。
|
||||
}
|
||||
|
||||
// 任务恢复
|
||||
-(void) resume {
|
||||
[self.task resume];
|
||||
(void) resume {
|
||||
[self.task resume];
|
||||
}
|
||||
|
||||
// 任务取消
|
||||
-(void) cancel {
|
||||
[self.task cancel];
|
||||
(void) cancel {
|
||||
[self.task cancel];
|
||||
}
|
||||
|
||||
// 任务挂起
|
||||
- (void)suspend {
|
||||
[self.task suspend];
|
||||
(void)suspend {
|
||||
[self.task suspend];
|
||||
}
|
||||
|
||||
@end
|
||||
@ -822,15 +796,15 @@ cmd 消息由服务端下发客户端解析。
|
||||
// 实现四个方法 initWithMessage resume cancel suspend
|
||||
@implementation WKFileDownloadTask
|
||||
|
||||
- (instancetype)initWithMessage:(WKMessage *)message {
|
||||
self = [super initWithMessage:message];
|
||||
if(self) {
|
||||
[self initTask];
|
||||
}
|
||||
return self;
|
||||
(instancetype)initWithMessage:(WKMessage *)message {
|
||||
self = [super initWithMessage:message];
|
||||
if(self) {
|
||||
[self initTask];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) initTask {
|
||||
(void) initTask {
|
||||
WKMediaContent *mediaContent = (WKMediaContent*)self.message.content;
|
||||
|
||||
NSString *downloadURL = mediaContent.remoteUrl; // 附件下载地址
|
||||
@ -852,17 +826,17 @@ cmd 消息由服务端下发客户端解析。
|
||||
}
|
||||
|
||||
// 任务恢复
|
||||
-(void) resume {
|
||||
[self.task resume];
|
||||
(void) resume {
|
||||
[self.task resume];
|
||||
}
|
||||
|
||||
// 任务取消
|
||||
-(void) cancel {
|
||||
[self.task cancel];
|
||||
(void) cancel {
|
||||
[self.task cancel];
|
||||
}
|
||||
|
||||
// 任务挂起
|
||||
- (void)suspend {
|
||||
(void)suspend {
|
||||
[self.task suspend];
|
||||
}
|
||||
|
||||
@ -899,37 +873,35 @@ cmd 消息由服务端下发客户端解析。
|
||||
|
||||
```
|
||||
|
||||
#### 第二步 编码解码
|
||||
|
||||
```objc
|
||||
|
||||
最终传递的消息内容为 {"type":3,"url":"xxxx","width":xxx,"height":xxx}
|
||||
// 最终传递的消息内容为 {"type":3,"url":"xxxx","width":xxx,"height":xxx}
|
||||
|
||||
@implementation WKGIFContent
|
||||
|
||||
// 定义消息正文类型
|
||||
+(NSInteger) contentType {
|
||||
(NSInteger) contentType {
|
||||
return 3;
|
||||
}
|
||||
|
||||
// 发送消息时对消息内容编码
|
||||
- (NSDictionary *)encodeWithJSON {
|
||||
NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
|
||||
[dataDict setObject:self.url?:@"" forKey:@"url"];
|
||||
[dataDict setObject:@(self.width) forKey:@"width"];
|
||||
[dataDict setObject:@(self.height) forKey:@"height"];
|
||||
return dataDict;
|
||||
(NSDictionary *)encodeWithJSON {
|
||||
NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
|
||||
[dataDict setObject:self.url?:@"" forKey:@"url"];
|
||||
[dataDict setObject:@(self.width) forKey:@"width"];
|
||||
[dataDict setObject:@(self.height) forKey:@"height"];
|
||||
return dataDict;
|
||||
}
|
||||
|
||||
// 收到消息时对消息内容解码
|
||||
- (void)decodeWithJSON:(NSDictionary *)contentDic {
|
||||
self.url = contentDic[@"url"];
|
||||
self.width = contentDic[@"width"]?[contentDic[@"width"] integerValue]:100;
|
||||
self.height = contentDic[@"height"]?[contentDic[@"height"] integerValue]:100;
|
||||
(void)decodeWithJSON:(NSDictionary *)contentDic {
|
||||
self.url = contentDic[@"url"];
|
||||
self.width = contentDic[@"width"]?[contentDic[@"width"] integerValue]:100;
|
||||
self.height = contentDic[@"height"]?[contentDic[@"height"] integerValue]:100;
|
||||
}
|
||||
|
||||
// 最近会话显示的内容
|
||||
- (NSString *)conversationDigest {
|
||||
(NSString *)conversationDigest {
|
||||
return @"[gif表情]"
|
||||
}
|
||||
|
||||
@ -952,7 +924,7 @@ cmd 消息由服务端下发客户端解析。
|
||||
|
||||
注意这里时继承 WKMediaMessageContent 不是 WKMessageContent
|
||||
|
||||
最终传递的消息内容为 {"type":4,"url":"xxxx","width":xxx,"height":xxx}
|
||||
最终传递的消息内容为 ```{"type":4,"url":"xxxx","width":xxx,"height":xxx}```
|
||||
|
||||
```objc
|
||||
|
||||
@ -967,36 +939,35 @@ cmd 消息由服务端下发客户端解析。
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
#### 第二步编码解码和将需要上传的数据写入本地路径
|
||||
|
||||
```objc
|
||||
@implementation WKImageContent
|
||||
|
||||
// 定义消息正文类型
|
||||
+(NSInteger) contentType {
|
||||
return 4;
|
||||
(NSInteger) contentType {
|
||||
return 4;
|
||||
}
|
||||
|
||||
// 将图片数据写入到本地路径,这样后面的上传任务会将此路径的附件上传到服务器
|
||||
- (void) writeDataToLocalPath {
|
||||
[super writeDataToLocalPath];
|
||||
[self.imageData writeToFile:self.localPath atomically:YES];
|
||||
(void) writeDataToLocalPath {
|
||||
[super writeDataToLocalPath];
|
||||
[self.imageData writeToFile:self.localPath atomically:YES];
|
||||
}
|
||||
|
||||
// 附件消息当附件上传成功后 会获取到上传后的self.remoteUrl下载地址,我们只需要将此下载地址编码到json里,附件的上传任务进度管理请查看 [WKSDK shared].mediaManager
|
||||
- (NSDictionary *)encodeWithJSON {
|
||||
NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
|
||||
[dataDict setObject:self.remoteUrl?:@"" forKey:@"url"];
|
||||
[dataDict setObject:@(self.width) forKey:@"width"];
|
||||
[dataDict setObject:@(self.height) forKey:@"height"];
|
||||
return dataDict;
|
||||
(NSDictionary *)encodeWithJSON {
|
||||
NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
|
||||
[dataDict setObject:self.remoteUrl?:@"" forKey:@"url"];
|
||||
[dataDict setObject:@(self.width) forKey:@"width"];
|
||||
[dataDict setObject:@(self.height) forKey:@"height"];
|
||||
return dataDict;
|
||||
}
|
||||
// 当收到消息需要解码,这时候我们只需要将下载地址url 赋值给self.remoteUrl后 下载任务会通过self.remoteUrl的下载地址进行下载附件 附件的下载任务进度管理请查看 [WKSDK shared].mediaManager
|
||||
- (void)decodeWithJSON:(NSDictionary *)contentDic {
|
||||
self.remoteUrl = contentDic[@"url"];
|
||||
self.width = contentDic[@"width"]?[contentDic[@"width"] floatValue]:0;
|
||||
self.height = contentDic[@"height"]?[contentDic[@"height"] floatValue]:0;
|
||||
(void)decodeWithJSON:(NSDictionary *)contentDic {
|
||||
self.remoteUrl = contentDic[@"url"];
|
||||
self.width = contentDic[@"width"]?[contentDic[@"width"] floatValue]:0;
|
||||
self.height = contentDic[@"height"]?[contentDic[@"height"] floatValue]:0;
|
||||
}
|
||||
|
||||
|
||||
@ -1101,17 +1072,17 @@ cmd 消息由服务端下发客户端解析。
|
||||
|
||||
```objc
|
||||
|
||||
// 提交编辑内容。
|
||||
[[[WKSDK shared] chatManager] setMessageEditProvider:^(WKMessageExtra * _Nonnull extra, WKMessageEditCallback _Nonnull callback) {
|
||||
// 提交编辑内容。
|
||||
[[[WKSDK shared] chatManager] setMessageEditProvider:^(WKMessageExtra * _Nonnull extra, WKMessageEditCallback _Nonnull callback) {
|
||||
|
||||
NSData *editContentData = extra.contentEditData; // 编辑后的正文数据
|
||||
NSData *editContentData = extra.contentEditData; // 编辑后的正文数据
|
||||
|
||||
// 请求自己的app服务端
|
||||
....
|
||||
// 请求自己的app服务端
|
||||
....
|
||||
|
||||
// 结果回调
|
||||
callback(result);
|
||||
}];
|
||||
// 结果回调
|
||||
callback(result);
|
||||
}];
|
||||
|
||||
```
|
||||
|
||||
@ -1134,7 +1105,7 @@ WKMessage *messageEditAfter = [[WKSDK shared].chatManager editMessage:(WKMessage
|
||||
|
||||
// ---------- WKChatManagerDelegate ----------
|
||||
|
||||
-(void) onMessageUpdate:(WKMessage*) message left:(NSInteger)left {
|
||||
(void) onMessageUpdate:(WKMessage*) message left:(NSInteger)left {
|
||||
WKMessageContent *orgContent = message.content; // 原始正文
|
||||
WKMessageContent *editContent = message.remoteExtra.contentEdit; // 编辑后的正文
|
||||
}
|
||||
@ -1175,7 +1146,7 @@ WKMessage *messageEditAfter = [[WKSDK shared].chatManager editMessage:(WKMessage
|
||||
|
||||
// ---------- WKReactionManagerDelegate ----------
|
||||
|
||||
-(void) reactionManagerChange:(WKReactionManager*)reactionManager reactions:(NSArray<WKReaction*>*)reactions channel:(WKChannel*)channel {
|
||||
(void) reactionManagerChange:(WKReactionManager*)reactionManager reactions:(NSArray<WKReaction*>*)reactions channel:(WKChannel*)channel {
|
||||
|
||||
}
|
||||
|
||||
@ -1207,7 +1178,6 @@ setting.receiptEnabled = true // 开启端消息回执
|
||||
}];
|
||||
|
||||
```
|
||||
|
||||
#### 数据操作
|
||||
|
||||
```objc
|
||||
@ -1227,10 +1197,10 @@ setting.receiptEnabled = true // 开启端消息回执
|
||||
@param message <#message description#>
|
||||
@param left 消息剩余数量 ,可当left为0时再刷新UI
|
||||
*/
|
||||
-(void) onMessageUpdate:(WKMessage*) message left:(NSInteger)left {
|
||||
if(message.remoteExtra.readed) {
|
||||
NSLog(@"消息已读");
|
||||
}
|
||||
(void) onMessageUpdate:(WKMessage*) message left:(NSInteger)left {
|
||||
if(message.remoteExtra.readed) {
|
||||
NSLog(@"消息已读");
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
@ -1282,6 +1252,16 @@ setting.signal = true // 开启端对端加密 (目前只有个人频道才有
|
||||
[[WKSDK shared].reminderManager done:(NSArray<NSNumber*>*)ids];
|
||||
```
|
||||
|
||||
#### 数据操作
|
||||
|
||||
```objc
|
||||
// 同步提醒
|
||||
[[WKSDK shared].reminderManager sync];
|
||||
|
||||
// 提醒项已处理完成
|
||||
[[WKSDK shared].reminderManager done:(NSArray<NSNumber*>*)ids];
|
||||
```
|
||||
|
||||
#### 数据监听
|
||||
|
||||
```objc
|
||||
@ -1289,7 +1269,7 @@ setting.signal = true // 开启端对端加密 (目前只有个人频道才有
|
||||
// ---------- WKReminderManagerDelegate ----------
|
||||
|
||||
// 某个频道的reminders发生变化
|
||||
-(void) reminderManager:(WKReminderManager*)manager didChange:(WKChannel*)channel reminders:(NSArray<WKReminder*>*) reminders {
|
||||
(void) reminderManager:(WKReminderManager*)manager didChange:(WKChannel*)channel reminders:(NSArray<WKReminder*>*) reminders {
|
||||
|
||||
}
|
||||
|
@ -1,21 +1,13 @@
|
||||
---
|
||||
title: Javascript
|
||||
order: 300
|
||||
---
|
||||
|
||||
# Javascript
|
||||
|
||||
## 介绍
|
||||
## 设计理念
|
||||
像设计书的目录一样设计 api, 通过 WKSDK.shared().xxxManager 我们可以访问到所有需要的功能,例如发送消息 WKSDK.shared().chatManager.send(xxx)
|
||||
|
||||
### 设计理念
|
||||
|
||||
像设计书的目录一样设计 api, 通过 WKSDK.shared().xxxManager 我们可以访问到所有需要的功能,例如发送消息 `WKSDK.shared().chatManager.send(xxx)`
|
||||
|
||||
### 结构说明
|
||||
## 结构说明
|
||||
|
||||

|
||||
|
||||
```ts
|
||||
``` js
|
||||
// 聊天管理者
|
||||
// 负责消息相关的增删改查操作 比如发送消息,删除消息,撤回消息,聊天消息的监听等等
|
||||
WKSDK.shared().chatManager;
|
||||
@ -36,28 +28,36 @@ WKSDK.shared().conversationManager;
|
||||
// 负责最近会话的提醒事项维护
|
||||
WKSDK.shared().reminderManager;
|
||||
```
|
||||
|
||||
## 集成
|
||||
|
||||
### npm 或 yarn 引入
|
||||
### 安装
|
||||
|
||||
```
|
||||
$ npm i wukongimjssdk
|
||||
::: code-group
|
||||
|
||||
``` sh [npm]
|
||||
npm i wukongimjssdk
|
||||
```
|
||||
|
||||
或者
|
||||
``` sh [yarn]
|
||||
yarn add wukongimjssdk
|
||||
```
|
||||
|
||||
``` sh [pnpm]
|
||||
pnpm add wukongimjssdk
|
||||
```
|
||||
$ yarn add wukongimjssdk
|
||||
```
|
||||
:::
|
||||
|
||||
|
||||
|
||||
### 引入
|
||||
|
||||
``` js
|
||||
import { WKSDK } from "wukongimjssdk/lib/sdk"
|
||||
```
|
||||
|
||||
### 初始化
|
||||
|
||||
```ts
|
||||
``` js
|
||||
// 集群模式通过此方法获取连接地址
|
||||
// WKSDK.shared().config.provider.connectAddrCallback = async (callback: ConnectAddrCallback) => {
|
||||
// const addr = await xxxx // addr 格式为 ip:port
|
||||
@ -76,7 +76,7 @@ WKSDK.shared().config;
|
||||
|
||||
## 连接与断开
|
||||
|
||||
```ts
|
||||
``` js
|
||||
// 连接
|
||||
WKSDK.shared().connectManager.connect();
|
||||
|
||||
@ -94,12 +94,10 @@ WKSDK.shared().connectManager.addConnectStatusListener(
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
## 在线消息收发
|
||||
### 数据操作
|
||||
|
||||
#### 数据操作
|
||||
|
||||
```ts
|
||||
``` js
|
||||
/**
|
||||
* 发送消息
|
||||
* @param content 消息内容
|
||||
@ -115,10 +113,9 @@ const text = new MessageText("hello")
|
||||
WKSDK.shared().chatManager.send(text,new Channel("A",ChannelTypePerson))
|
||||
|
||||
```
|
||||
### 数据监听
|
||||
|
||||
#### 数据监听
|
||||
|
||||
```ts
|
||||
``` js
|
||||
// 消息发送状态监听
|
||||
WKSDK.shared().chatManager.addMessageStatusListener((packet: SendackPacket) => {
|
||||
console.log('消息clientSeq->', packet.clientSeq); // 客户端序号用来匹配对应的发送的消息
|
||||
@ -132,14 +129,11 @@ WKSDK.shared().chatManager.addMessageStatusListener((packet: SendackPacket) => {
|
||||
// 消息监听
|
||||
WKSDK.shared().chatManager.addMessageListener((message: Message) => {});
|
||||
```
|
||||
|
||||
## 离线消息接收
|
||||
在悟空 **IM**中为了应付海量离线消息,采用了按需拉取的机制,比如 10 个会话一个会话 10 万条消息,**悟空 IM** 不会把这个 **1010** 万=100 万条消息都拉取到本地。 而是采用拉取这 10 个会话的信息和对应的最新 20 条消息,也就是实际只拉取了 200 条消息 相对 100 万条消息来说大大提高了离线拉取速度。用户点进对应的会话才会去按需拉取这个会话的消息。 这些机制 SDK 内部都已做好了封装,使用者其实不需要关心。使用者只需要关心最近会话的变化
|
||||
### 数据源设置
|
||||
|
||||
在**悟空 IM**中为了应付海量离线消息,采用了按需拉取的机制,比如 10 个会话一个会话 10 万条消息,\**悟空 IM 不会把这个 10*10 万=100 万条消息都拉取到本地。 而是采用拉取这 10 个会话的信息和对应的最新 20 条消息,也就是实际只拉取了 200 条消息 相对 100 万条消息来说大大提高了离线拉取速度。用户点进对应的会话才会去按需拉取这个会话的消息。 这些机制 SDK 内部都已做好了封装,使用者其实不需要关心。使用者只需要关心最近会话的变化
|
||||
|
||||
#### 数据源设置
|
||||
|
||||
```ts
|
||||
``` js
|
||||
|
||||
// 提供最近会话同步的数据源
|
||||
WKSDK.shared().config.provider.syncConversationsCallback = async (): Promise<Array<Conversation>> => {
|
||||
@ -160,20 +154,18 @@ WKSDK.shared().config.provider.syncMessagesCallback = async(channel:Channel,opts
|
||||
}
|
||||
|
||||
```
|
||||
### 数据操作
|
||||
|
||||
##### 数据操作
|
||||
|
||||
```ts
|
||||
``` js
|
||||
// 同步最近会话(会触发WKSDK.shared().config.provider.syncConversationsCallback)
|
||||
const conversations = await WKSDK.shared().conversationManager.sync({});
|
||||
|
||||
// 同步频道的消息(会触发WKSDK.shared().config.provider.syncMessagesCallback)
|
||||
const messages = WKSDK.shared().chatManager.syncMessages(channel, opts);
|
||||
```
|
||||
### 数据监听
|
||||
|
||||
##### 数据监听
|
||||
|
||||
```ts
|
||||
``` js
|
||||
// 监听最近会话数据
|
||||
WKSDK.shared().conversationManager.addConversationListener(
|
||||
(conversation: Conversation, action: ConversationAction) => {
|
||||
@ -182,10 +174,9 @@ WKSDK.shared().conversationManager.addConversationListener(
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
## 文本消息
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
class MessageText extends MessageContent {
|
||||
text?: string;
|
||||
}
|
||||
@ -193,7 +184,7 @@ class MessageText extends MessageContent {
|
||||
|
||||
## 图片消息
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
class ImageContent extends MediaMessageContent {
|
||||
width!: number; // 图片宽度
|
||||
height!: number; // 图片高度
|
||||
@ -208,22 +199,19 @@ class ImageContent extends MediaMessageContent {
|
||||
```
|
||||
|
||||
## 语音消息
|
||||
|
||||
web 语音消息暂只支持收不支持发送
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
class VoiceContent extends MediaMessageContent {
|
||||
url!: string; // 语音文件下载地址
|
||||
timeTrad!: number; // 语音秒长
|
||||
waveform!: string; // 语音波纹 base64编码
|
||||
}
|
||||
```
|
||||
|
||||
## 小视频消息
|
||||
|
||||
web 语小视频消息暂只支持收不支持发送
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
class VideoContent extends MessageContent {
|
||||
url!: string; // 小视频下载地址
|
||||
cover!: string; // 小视频封面图片下载地址
|
||||
@ -233,10 +221,9 @@ class VideoContent extends MessageContent {
|
||||
second!: number; // 小视频秒长
|
||||
}
|
||||
```
|
||||
|
||||
## 名片消息
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
class Card extends MessageContent {
|
||||
name!: string; // 好友名字
|
||||
uid!: string; // 好友uid
|
||||
@ -246,7 +233,7 @@ class Card extends MessageContent {
|
||||
|
||||
## 位置消息
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
class LocationContent extends MessageContent {
|
||||
lng: number = 0; // 纬度
|
||||
lat: number = 0; // 经度
|
||||
@ -257,26 +244,22 @@ class LocationContent extends MessageContent {
|
||||
```
|
||||
|
||||
## CMD 消息
|
||||
|
||||
cmd 消息由服务端下发客户端解析执行。
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
class CMDContent extends MessageContent {
|
||||
cmd!: string; // cmd的指令
|
||||
param: any; // 指令对应的参数
|
||||
}
|
||||
```
|
||||
|
||||
## 最近会话
|
||||
|
||||
最近会话用于表示会话列表页的数据模型。当用户发送,收取及删除消息时,都会同时去修改最近会话。
|
||||
|
||||
当收到或者一条消息时,会自动生成这个消息对应的最近会话。但值得注意的是最近会话和会话并不是一一对应的关系,删除最近会话并不会影响会话
|
||||
当收到或者一条消息时,会自动生成这个消息对应的最近会话。但值得注意的是最近会话和会话并不是一一对应的关系,删除最近会话并不影响会话
|
||||
|
||||
最近会话主要属性
|
||||
|
||||
```ts
|
||||
|
||||
``` ts
|
||||
class Conversation {
|
||||
channel!: Channel; // 频道
|
||||
unread!: number; // 未读消息
|
||||
@ -286,9 +269,7 @@ class Conversation {
|
||||
reminders = new Array<Reminder>() // 提醒项
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 频道管理(置顶,免打扰等等)
|
||||
|
||||
[什么是频道](/guide/initialize#频道)
|
||||
@ -318,10 +299,9 @@ class ChannelInfo {
|
||||
orgData: any; // 频道原始数据由第三方自定义
|
||||
}
|
||||
```
|
||||
### 数据源设置
|
||||
|
||||
#### 数据源设置
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
// 频道详情获取数据源提供
|
||||
WKSDK.shared().config.provider.channelInfoCallback = async function (channel: Channel): Promise<ChannelInfo> {
|
||||
let channelInfo:ChannelInfo
|
||||
@ -337,10 +317,9 @@ class ChannelInfo {
|
||||
}
|
||||
|
||||
```
|
||||
### 数据操作
|
||||
|
||||
#### 数据操作
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
// 获取频道详情(不会触发数据源的远程获取)
|
||||
const channelInfo = WKSDK.shared().channelManager.getChannelInfo(channel);
|
||||
|
||||
@ -353,10 +332,9 @@ WKSDK.shared().channelManager.fetchChannelInfo(channel);
|
||||
// 从远程提取频道列表(会触发数据源的远程获取和订阅者的监听,是异步过程)
|
||||
WKSDK.shared().channelManager.syncSubscribes(channel);
|
||||
```
|
||||
### 数据监听
|
||||
|
||||
#### 数据监听
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
// 监听频道详情
|
||||
WKSDK.shared().channelManager.addListener((channelInfo: ChannelInfo) => {});
|
||||
```
|
||||
@ -364,73 +342,69 @@ WKSDK.shared().channelManager.addListener((channelInfo: ChannelInfo) => {});
|
||||
## 进阶使用
|
||||
|
||||
### 消息附件上传设置
|
||||
|
||||
所有带附件的消息的上传都会通过此任务上传
|
||||
|
||||
伪代码如下:
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
|
||||
// 实现四个方法 initWithMessage resume cancel suspend
|
||||
class MediaMessageUploadTask extends MessageTask {
|
||||
|
||||
- (instancetype)initWithMessage:(WKMessage *)message {
|
||||
self = [super initWithMessage:message];
|
||||
if(self) {
|
||||
[self initTask];
|
||||
}
|
||||
- (instancetype)initWithMessage:(WKMessage *)message {
|
||||
self = [super initWithMessage:message];
|
||||
if(self) {
|
||||
[self initTask];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
async start(): Promise<void> {
|
||||
const mediaContent = this.message.content as MediaMessageContent
|
||||
const param = new FormData();
|
||||
param.append("file", mediaContent.file);
|
||||
const resp = await axios.post(uploadURL,param,{
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
cancelToken: new axios.CancelToken((c: Canceler) => {
|
||||
this.canceler = c
|
||||
}),
|
||||
onUploadProgress: e => {
|
||||
// 更新任务进度
|
||||
var completeProgress = ((e.loaded / e.total) | 0);
|
||||
this._progress = completeProgress
|
||||
this.update()
|
||||
}
|
||||
}).catch(error => {
|
||||
// 更新任务错误
|
||||
console.log('文件上传失败!->', error);
|
||||
this.status = TaskStatus.fail
|
||||
this.update()
|
||||
async start(): Promise<void> {
|
||||
const mediaContent = this.message.content as MediaMessageContent
|
||||
const param = new FormData();
|
||||
param.append("file", mediaContent.file);
|
||||
const resp = await axios.post(uploadURL,param,{
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
cancelToken: new axios.CancelToken((c: Canceler) => {
|
||||
this.canceler = c
|
||||
}),
|
||||
onUploadProgress: e => {
|
||||
// 更新任务进度
|
||||
var completeProgress = ((e.loaded / e.total) | 0);
|
||||
this._progress = completeProgress
|
||||
this.update()
|
||||
}
|
||||
}).catch(error => {
|
||||
// 更新任务错误
|
||||
console.log('文件上传失败!->', error);
|
||||
this.status = TaskStatus.fail
|
||||
this.update()
|
||||
})
|
||||
if(resp) {
|
||||
if(resp.data.path) {
|
||||
// 更新任务成功
|
||||
const mediaContent = this.message.content as MediaMessageContent
|
||||
mediaContent.remoteUrl = resp.data.path
|
||||
this.status = TaskStatus.success
|
||||
this.update()
|
||||
}
|
||||
if(resp.data.path) {
|
||||
// 更新任务成功
|
||||
const mediaContent = this.message.content as MediaMessageContent
|
||||
mediaContent.remoteUrl = resp.data.path
|
||||
this.status = TaskStatus.success
|
||||
this.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 任务取消
|
||||
cancel(): void {
|
||||
this.status = TaskStatus.cancel
|
||||
if(this.canceler) {
|
||||
this.canceler()
|
||||
}
|
||||
this.update()
|
||||
// 任务取消
|
||||
cancel(): void {
|
||||
this.status = TaskStatus.cancel
|
||||
if(this.canceler) {
|
||||
this.canceler()
|
||||
}
|
||||
this.update()
|
||||
}
|
||||
|
||||
// 任务进度
|
||||
progress(): number {
|
||||
return this._progress??0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 任务进度
|
||||
progress(): number {
|
||||
return this._progress??0
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
```
|
||||
|
||||
注册上传任务
|
||||
@ -442,11 +416,9 @@ WKSDK.shared().config.provider.messageUploadTaskCallback = (
|
||||
return new MediaMessageUploadTask(message);
|
||||
};
|
||||
```
|
||||
|
||||
### 自定义普通消息
|
||||
|
||||
我们以自定义一个 gif 消息为例。
|
||||
|
||||
#### 第一步继承 MessageContent 和定义 gif 消息的正文结构
|
||||
|
||||
```ts
|
||||
@ -461,7 +433,7 @@ class GifContent extends MessageContent {
|
||||
|
||||
```ts
|
||||
|
||||
最终传递的消息内容为 {"type":3,"url":"xxxx","width":xxx,"height":xxx}
|
||||
// 最终传递的消息内容为 {"type":3,"url":"xxxx","width":xxx,"height":xxx}
|
||||
|
||||
class GifContent extends MessageContent {
|
||||
width!: number // gif宽度
|
||||
@ -482,7 +454,6 @@ class GifContent extends MessageContent {
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### 第三步 注册
|
||||
|
||||
```ts
|
||||
@ -497,7 +468,7 @@ WKSDK.shared().register(MessageContentTypeConst.gif, () => new GifContent()); //
|
||||
|
||||
注意这里是继承 MediaMessageContent 不是 MessageContent,当发送附件消息的时候,sdk 会调用[上传任务](/web/onlysdk.html#消息附件上传设置),将本地的文件上传到服务器,然后再进行消息的编码和发送
|
||||
|
||||
最终传递的消息内容为 {"type":4,"url":"xxxx","width":xxx,"height":xxx}
|
||||
最终传递的消息内容为 ```{"type":4,"url":"xxxx","width":xxx,"height":xxx}```
|
||||
|
||||
```ts
|
||||
|
||||
@ -507,7 +478,6 @@ class ImageContent : MediaMessageContent {
|
||||
url!: string // gif远程下载地址
|
||||
}
|
||||
```
|
||||
|
||||
#### 第二步编码解码
|
||||
|
||||
```ts
|
||||
@ -571,12 +541,12 @@ web 不支持端对端加密
|
||||
|
||||
会话提醒目前只支持服务端下发指令,客户端同步提醒然后显示提醒,会话提醒由 WKSDK.shared().reminderManager 管理
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
class Reminder {
|
||||
channel!: Channel;
|
||||
reminderID!: number; // 提醒ID
|
||||
messageID!: string;
|
||||
messageSeq!: number;
|
||||
channel: Channel;
|
||||
reminderID: number; // 提醒ID
|
||||
messageID: string;
|
||||
messageSeq: number;
|
||||
reminderType!: ReminderType; // 提醒类型
|
||||
text?: string; // 文本提示
|
||||
data?: any; // 提醒包含的自定义数据
|
||||
@ -602,7 +572,6 @@ class Reminder {
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
###### 数据操作
|
||||
|
||||
```ts
|
||||
@ -623,3 +592,4 @@ WKSDK.shared().conversationManager.addConversationListener(
|
||||
},
|
||||
);
|
||||
```
|
||||
|
Before Width: | Height: | Size: 591 KiB After Width: | Height: | Size: 591 KiB |
Before Width: | Height: | Size: 335 KiB After Width: | Height: | Size: 335 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
BIN
src/sdk/wksdk.png
Normal file
After Width: | Height: | Size: 382 KiB |
@ -1,14 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"jsx": "react",
|
||||
"jsx": "react",
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@@/*": [".dumi/tmp/*"]
|
||||
}
|
||||
},
|
||||
"include": [".dumi/**/*", ".dumirc.ts"]
|
||||
}
|
7
uno.config.ts
Normal file
@ -0,0 +1,7 @@
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { defineConfig, presetAttributify, presetIcons, presetUno, transformerDirectives } from "unocss";
|
||||
|
||||
export default defineConfig({
|
||||
presets: [presetUno(), presetIcons(), presetAttributify()],
|
||||
transformers: [transformerDirectives()],
|
||||
});
|