Skip to content

Commit d90b8c1

Browse files
authored
Merge pull request #172 from capdiem/feature/widget-dev-watch
chore (widget): adds a sample and watch mode for development
2 parents f6db991 + 72a8542 commit d90b8c1

File tree

8 files changed

+576
-25
lines changed

8 files changed

+576
-25
lines changed

web/package-lock.json

Lines changed: 431 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"dev": "next dev",
55
"build": "next build && npm run build:widget",
66
"build:widget": "node widget-build.js",
7+
"dev:widget": "node widget-build.js --watch",
78
"start": "next start",
89
"lint": "next lint"
910
},

web/public/koala-chat-widget.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/public/koala-chat-widget.js.map

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/samples/widget.html

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!DOCTYPE html>
2+
<html lang="zh-CN">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>KoalaWiki Chat Widget 测试</title>
7+
<style>
8+
body {
9+
font-family: 'Arial', sans-serif;
10+
line-height: 1.6;
11+
margin: 0;
12+
padding: 20px;
13+
max-width: 800px;
14+
margin: 0 auto;
15+
}
16+
h1 {
17+
color: #333;
18+
border-bottom: 1px solid #eee;
19+
padding-bottom: 10px;
20+
}
21+
.content {
22+
margin-top: 20px;
23+
}
24+
</style>
25+
</head>
26+
<body>
27+
<h1>KoalaWiki Chat Widget 测试页面</h1>
28+
29+
<div class="content">
30+
<p>这是一个简单的测试页面,展示了 KoalaWiki 聊天悬浮球组件的基本用法。</p>
31+
<p>右下角应该会出现聊天悬浮球按钮。</p>
32+
</div>
33+
34+
<script src="../public/koala-chat-widget.js"></script>
35+
36+
<script>
37+
KoalaChatWidget.init({
38+
appId: 'app_mcpx2xlc_udcn5c',
39+
title: 'AI 助手',
40+
apiUrl: 'https://opendeep.wiki',
41+
theme: 'light'
42+
});
43+
</script>
44+
</body>
45+
</html>

web/widget-build.js

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
/**
2-
* esbuild 配置文件
3-
* 用于打包 widget 代码并压缩内联 CSS
2+
* esbuild 统一构建脚本
3+
* 支持普通构建和监视模式
4+
*
5+
* 使用方式:
6+
* - node widget-build.js # 普通构建模式
7+
* - node widget-build.js --watch # 监视模式
48
*/
59

610
const esbuild = require('esbuild');
711
const fs = require('fs');
812
const path = require('path');
913

14+
// 检查是否为监视模式
15+
const isWatchMode = process.argv.includes('--watch');
16+
1017
// CSS 压缩函数
1118
function minifyCSS(css) {
1219
return css
@@ -41,24 +48,70 @@ const cssMinifierPlugin = {
4148
}
4249
};
4350

44-
// 打包配置
45-
async function build() {
51+
// 构建配置
52+
const buildOptions = {
53+
entryPoints: ['widget/index.ts'],
54+
bundle: true,
55+
minify: true,
56+
sourcemap: true,
57+
platform: 'browser',
58+
outfile: 'public/koala-chat-widget.js',
59+
plugins: [cssMinifierPlugin],
60+
};
61+
62+
// 监视模式
63+
async function watchBuild() {
4664
try {
47-
const result = await esbuild.build({
48-
entryPoints: ['widget/index.ts'],
49-
bundle: true,
50-
minify: true,
51-
sourcemap: true,
52-
platform: 'browser',
53-
outfile: 'public/koala-chat-widget.js',
54-
plugins: [cssMinifierPlugin],
65+
const ctx = await esbuild.context({
66+
...buildOptions,
67+
plugins: [
68+
...buildOptions.plugins,
69+
{
70+
name: 'watch-plugin',
71+
setup(build) {
72+
build.onEnd(result => {
73+
if (result.errors.length > 0) {
74+
console.error('❌ Build failed:', result.errors);
75+
} else {
76+
const timestamp = new Date().toLocaleTimeString();
77+
console.log(`🔄 [${timestamp}] File change detected, rebuild successful`);
78+
}
79+
});
80+
},
81+
},
82+
],
5583
});
5684

57-
console.log('✅ Widget 构建成功');
85+
// 启动监视模式
86+
await ctx.watch();
87+
88+
console.log('👀 Watching widget files for changes...');
89+
console.log('✅ Initial build complete');
90+
console.log('📝 Changes to files in widget/ directory will trigger automatic rebuild');
91+
console.log('💡 Press Ctrl+C to stop watching');
92+
93+
// 保持进程运行
94+
await new Promise(() => {}); // 永不解决的 Promise
95+
} catch (error) {
96+
console.error('❌ Widget watch mode failed to start:', error);
97+
process.exit(1);
98+
}
99+
}
100+
101+
// 单次构建
102+
async function singleBuild() {
103+
try {
104+
await esbuild.build(buildOptions);
105+
console.log('✅ Widget build successful');
58106
} catch (error) {
59-
console.error('❌ Widget 构建失败:', error);
107+
console.error('❌ Widget build failed:', error);
60108
process.exit(1);
61109
}
62110
}
63111

64-
build();
112+
// 根据模式执行不同的构建函数
113+
if (isWatchMode) {
114+
watchBuild();
115+
} else {
116+
singleBuild();
117+
}

web/widget/index.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
* <script src="https://your-domain.com/koala-chat-widget.js"></script>
77
* <script>
88
* KoalaChatWidget.init({
9-
* appId: 'your-app-id',
10-
* organizationName: 'your-org',
11-
* repositoryName: 'your-repo',
12-
* title: '我的 AI 助手',
13-
* expandIcon: 'base64-icon-data',
14-
* closeIcon: 'base64-icon-data',
15-
* apiUrl: 'https://your-api-domain.com'
9+
* appId: 'your-app-id', // 必填:应用ID,用于验证域名
10+
* apiUrl: 'https://opendeep.wiki', // 必填:API服务器地址
11+
*
12+
* // 以下参数都是可选的
13+
* title: '我的 AI 助手', // 可选:标题(可能被验证接口返回的配置覆盖)
14+
* theme: 'light', // 可选:主题 'light'|'dark'
15+
*
16+
* // UI自定义
17+
* expandIcon: null, // 可选:展开图标
18+
* closeIcon: null, // 可选:关闭图标
1619
* });
1720
* </script>
1821
*/

web/widget/types.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface KoalaChatWidgetConfig {
1616
tooltipDuration?: number;
1717
tooltipRepeatDelay?: number;
1818
onError?: (errorMessage: string) => void;
19+
onValidationFailed?: (domain: string) => void;
1920
}
2021

2122
/**
@@ -30,6 +31,23 @@ export interface KoalaChatWidgetAPI {
3031
toggle(): void;
3132
}
3233

34+
export interface ValidationResponse {
35+
isValid: boolean;
36+
reason?: string;
37+
appConfig?: {
38+
appId: string;
39+
name?: string;
40+
isEnabled: boolean;
41+
organizationName: string;
42+
repositoryName: string;
43+
allowedDomains: string[];
44+
enableDomainValidation: boolean;
45+
description?: string;
46+
createdAt?: Date;
47+
updatedAt?: Date;
48+
};
49+
}
50+
3351
// 声明全局Window接口扩展
3452
declare global {
3553
interface Window {

0 commit comments

Comments
 (0)