koishi-plugin-chatluna-toolbox 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ <!--
2
+ Toolbox 详情加载器
3
+ 根据当前插件名称决定是否显示共享导航组件
4
+ -->
5
+ <template>
6
+ <SharedNav v-if="isOwn" :sections="navSections" />
7
+ </template>
8
+
9
+ <script setup lang="ts">
10
+ import { ComputedRef, computed, inject } from "vue";
11
+ import { SharedNav } from "shared-nav";
12
+ import { NAV_SECTIONS, PLUGIN_CANDIDATE_NAMES } from "./constants";
13
+
14
+ const pluginName = inject<ComputedRef<string>>("plugin:name");
15
+ const navSections = NAV_SECTIONS;
16
+ const isOwn = computed(() => {
17
+ const name = pluginName?.value || "";
18
+ return PLUGIN_CANDIDATE_NAMES.includes(name);
19
+ });
20
+ </script>
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 前端常量定义
3
+ * 包含导航分组和插件候选名称
4
+ */
5
+
6
+ import type { SharedNavSection } from "shared-nav";
7
+
8
+ export const NAV_SECTIONS: SharedNavSection[] = [
9
+ { title: "基础设置", key: "basic" },
10
+ { title: "原生工具", key: "nativeTools" },
11
+ { title: "XML 工具", key: "xmlTools" },
12
+ { title: "其他变量", key: "variables" },
13
+ { title: "其他设置", key: "other" },
14
+ ];
15
+
16
+ export const PLUGIN_CANDIDATE_NAMES = [
17
+ "chatluna-toolbox",
18
+ "koishi-plugin-chatluna-toolbox",
19
+ ];
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 前端入口
3
+ * 注册 Koishi 控制台插件详情扩展
4
+ */
5
+
6
+ import { Context } from "@koishijs/client";
7
+ import ToolboxDetailsLoader from "./ToolboxDetailsLoader.vue";
8
+
9
+ export default (ctx: Context) => {
10
+ ctx.slot({
11
+ type: "plugin-details",
12
+ component: ToolboxDetailsLoader,
13
+ order: -999,
14
+ });
15
+ };
package/dist/index.js ADDED
@@ -0,0 +1,264 @@
1
+ import { openBlock as y, createElementBlock as _, createElementVNode as w, defineComponent as b, Fragment as E, renderList as N, normalizeClass as m, toDisplayString as z, reactive as I, computed as f, onUnmounted as L, ref as T, onMounted as B, normalizeStyle as A, unref as k, createVNode as x, withModifiers as D, inject as K, createBlock as X, createCommentVNode as O } from "vue";
2
+ const M = (s, o) => {
3
+ const r = s.__vccOpts || s;
4
+ for (const [c, t] of o)
5
+ r[c] = t;
6
+ return r;
7
+ }, V = {}, Y = {
8
+ viewBox: "0 0 1024 1024",
9
+ xmlns: "http://www.w3.org/2000/svg",
10
+ width: "20",
11
+ height: "20"
12
+ };
13
+ function q(s, o) {
14
+ return y(), _("svg", Y, [...o[0] || (o[0] = [
15
+ w("path", {
16
+ d: "M288 224c0-35.3 28.7-64 64-64s64 28.7 64 64-28.7 64-64 64-64-28.7-64-64zm320 0c0-35.3 28.7-64 64-64s64 28.7 64 64-28.7 64-64 64-64-28.7-64-64zM288 512c0-35.3 28.7-64 64-64s64 28.7 64 64-28.7 64-64 64-64-28.7-64-64zm320 0c0-35.3 28.7-64 64-64s64 28.7 64 64-28.7 64-64 64-64-28.7-64-64zM352 864c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64zm320 0c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64z",
17
+ fill: "currentColor"
18
+ }, null, -1)
19
+ ])]);
20
+ }
21
+ const P = /* @__PURE__ */ M(V, [["render", q]]), W = {}, j = {
22
+ viewBox: "0 0 1024 1024",
23
+ xmlns: "http://www.w3.org/2000/svg",
24
+ width: "20",
25
+ height: "20"
26
+ };
27
+ function U(s, o) {
28
+ return y(), _("svg", j, [...o[0] || (o[0] = [
29
+ w("path", {
30
+ d: "M831.872 340.864 512 652.672 192.128 340.864a30.592 30.592 0 0 0-42.752 0 29.12 29.12 0 0 0 0 41.6L489.664 714.24a32 32 0 0 0 44.672 0l340.288-331.712a29.12 29.12 0 0 0 0-41.728 30.592 30.592 0 0 0-42.752 0z",
31
+ fill: "currentColor"
32
+ }, null, -1)
33
+ ])]);
34
+ }
35
+ const F = /* @__PURE__ */ M(W, [["render", U]]), G = ["onClick"], H = /* @__PURE__ */ b({
36
+ __name: "NavSection",
37
+ props: {
38
+ sections: {},
39
+ activeKey: {}
40
+ },
41
+ emits: ["select"],
42
+ setup(s) {
43
+ return (o, r) => (y(!0), _(E, null, N(s.sections, (c) => (y(), _("div", {
44
+ key: c.key,
45
+ class: m([o.$style.item, s.activeKey === c.key ? o.$style.active : ""]),
46
+ onClick: (t) => o.$emit("select", c)
47
+ }, z(c.title), 11, G))), 128));
48
+ }
49
+ }), J = "_item_1m2kp_1", Q = "_active_1m2kp_16", Z = {
50
+ item: J,
51
+ active: Q
52
+ }, tt = {
53
+ $style: Z
54
+ }, et = /* @__PURE__ */ M(H, [["__cssModules", tt]]);
55
+ function R(s) {
56
+ return s instanceof TouchEvent ? {
57
+ x: s.touches[0].clientX,
58
+ y: s.touches[0].clientY
59
+ } : {
60
+ x: s.clientX,
61
+ y: s.clientY
62
+ };
63
+ }
64
+ function ot(s = {}) {
65
+ const {
66
+ initialTop: o = 100,
67
+ initialRight: r = 20,
68
+ boundarySelector: c = ".plugin-view"
69
+ } = s, t = I({
70
+ isDragging: !1,
71
+ top: o,
72
+ right: r,
73
+ startTop: 0,
74
+ startRight: 0,
75
+ startX: 0,
76
+ startY: 0,
77
+ width: 0,
78
+ height: 0
79
+ }), g = f(() => ({
80
+ top: `${t.top}px`,
81
+ right: `${t.right}px`
82
+ })), i = (d) => {
83
+ var C;
84
+ if (!t.isDragging)
85
+ return;
86
+ const a = R(d), l = t.startTop + (a.y - t.startY), e = t.startRight - (a.x - t.startX), n = (C = document.querySelector(c)) == null ? void 0 : C.getBoundingClientRect();
87
+ let h = 0, v = window.innerHeight - t.height, S = 0, $ = window.innerWidth - t.width;
88
+ n && (h = n.top, v = n.bottom - t.height, S = window.innerWidth - n.right, $ = window.innerWidth - n.left - t.width), t.top = Math.max(h, Math.min(v, l)), t.right = Math.max(S, Math.min($, e));
89
+ }, p = (d, a) => {
90
+ const l = R(d), e = a == null ? void 0 : a.getBoundingClientRect();
91
+ e && (t.width = e.width, t.height = e.height), t.startTop = t.top, t.startRight = t.right, t.startX = l.x, t.startY = l.y, t.isDragging = !0;
92
+ }, u = () => {
93
+ t.isDragging = !1;
94
+ };
95
+ return window.addEventListener("mousemove", i), window.addEventListener("mouseup", u), window.addEventListener("touchmove", i), window.addEventListener("touchend", u), L(() => {
96
+ window.removeEventListener("mousemove", i), window.removeEventListener("mouseup", u), window.removeEventListener("touchmove", i), window.removeEventListener("touchend", u);
97
+ }), {
98
+ position: g,
99
+ startDrag: p
100
+ };
101
+ }
102
+ function nt(s) {
103
+ const {
104
+ titleToKeyMap: o,
105
+ headerSelector: r = ".k-schema-header",
106
+ rootMargin: c = "-20% 0px -60% 0px",
107
+ threshold: t = 0
108
+ } = s, g = T("");
109
+ let i = null;
110
+ const p = /* @__PURE__ */ new Map(), u = () => {
111
+ i == null || i.disconnect(), p.clear(), i = new IntersectionObserver(
112
+ (l) => {
113
+ for (const e of l) {
114
+ if (!e.isIntersecting)
115
+ continue;
116
+ const n = p.get(e.target);
117
+ n && (g.value = n);
118
+ }
119
+ },
120
+ {
121
+ root: null,
122
+ rootMargin: c,
123
+ threshold: t
124
+ }
125
+ ), document.querySelectorAll(r).forEach((l) => {
126
+ const e = l.textContent || "";
127
+ for (const [n, h] of Object.entries(o))
128
+ if (e.includes(n)) {
129
+ i == null || i.observe(l), p.set(l, h);
130
+ break;
131
+ }
132
+ });
133
+ }, d = () => {
134
+ setTimeout(u, 500);
135
+ };
136
+ return B(d), L(() => {
137
+ i == null || i.disconnect();
138
+ }), {
139
+ activeSection: g,
140
+ refresh: d
141
+ };
142
+ }
143
+ const st = /* @__PURE__ */ b({
144
+ __name: "SharedNav",
145
+ props: {
146
+ sections: {},
147
+ headerSelector: { default: ".k-schema-header" },
148
+ boundarySelector: { default: ".plugin-view" },
149
+ initialTop: { default: 100 },
150
+ initialRight: { default: 20 },
151
+ rootMargin: { default: "-20% 0px -60% 0px" },
152
+ threshold: { default: 0 }
153
+ },
154
+ setup(s) {
155
+ const o = s, r = T(!1), c = T(null), t = f(
156
+ () => o.sections.reduce(
157
+ (e, n) => (e[n.matchText ?? n.title] = n.key, e),
158
+ {}
159
+ )
160
+ ), g = f(
161
+ () => o.sections.reduce(
162
+ (e, n) => (e[n.key] = n.matchText ?? n.title, e),
163
+ {}
164
+ )
165
+ ), i = (e) => {
166
+ e.stopPropagation(), r.value = !r.value;
167
+ }, { position: p, startDrag: u } = ot({
168
+ initialTop: o.initialTop,
169
+ initialRight: o.initialRight,
170
+ boundarySelector: o.boundarySelector
171
+ }), d = (e) => {
172
+ u(e, c.value);
173
+ }, { activeSection: a } = nt({
174
+ titleToKeyMap: t.value,
175
+ headerSelector: o.headerSelector,
176
+ rootMargin: o.rootMargin,
177
+ threshold: o.threshold
178
+ }), l = (e) => {
179
+ a.value = e.key;
180
+ const n = document.querySelectorAll(o.headerSelector);
181
+ for (let h = 0; h < n.length; h += 1) {
182
+ const v = n[h];
183
+ if ((v.textContent || "").includes(g.value[e.key])) {
184
+ v.scrollIntoView({ behavior: "smooth", block: "start" });
185
+ return;
186
+ }
187
+ }
188
+ };
189
+ return (e, n) => (y(), _("div", {
190
+ ref_key: "containerRef",
191
+ ref: c,
192
+ class: m([e.$style.container, r.value ? e.$style.collapsed : ""]),
193
+ style: A(k(p))
194
+ }, [
195
+ w("div", {
196
+ class: m(e.$style.header),
197
+ onMousedown: d,
198
+ onTouchstart: d
199
+ }, [
200
+ x(P, {
201
+ class: m(e.$style.move)
202
+ }, null, 8, ["class"]),
203
+ w("div", {
204
+ class: m(e.$style.toggle),
205
+ onClick: i,
206
+ onMousedown: n[0] || (n[0] = D(() => {
207
+ }, ["stop"])),
208
+ onTouchstart: n[1] || (n[1] = D(() => {
209
+ }, ["stop"]))
210
+ }, [
211
+ x(F)
212
+ ], 34)
213
+ ], 34),
214
+ w("div", {
215
+ class: m(e.$style.body)
216
+ }, [
217
+ x(et, {
218
+ sections: s.sections,
219
+ "active-key": k(a),
220
+ onSelect: l
221
+ }, null, 8, ["sections", "active-key"])
222
+ ], 2)
223
+ ], 6));
224
+ }
225
+ }), it = "_container_pbgsl_2", ct = "_header_pbgsl_21", rt = "_move_pbgsl_36", lt = "_toggle_pbgsl_45", at = "_body_pbgsl_56", dt = "_collapsed_pbgsl_67", ut = {
226
+ container: it,
227
+ header: ct,
228
+ move: rt,
229
+ toggle: lt,
230
+ body: at,
231
+ collapsed: dt
232
+ }, ht = {
233
+ $style: ut
234
+ }, gt = /* @__PURE__ */ M(st, [["__cssModules", ht]]), pt = [
235
+ { title: "基础设置", key: "basic" },
236
+ { title: "原生工具", key: "nativeTools" },
237
+ { title: "XML 工具", key: "xmlTools" },
238
+ { title: "其他变量", key: "variables" },
239
+ { title: "其他设置", key: "other" }
240
+ ], mt = [
241
+ "chatluna-toolbox",
242
+ "koishi-plugin-chatluna-toolbox"
243
+ ], yt = /* @__PURE__ */ b({
244
+ __name: "ToolboxDetailsLoader",
245
+ setup(s) {
246
+ const o = K("plugin:name"), r = pt, c = f(() => {
247
+ const t = (o == null ? void 0 : o.value) || "";
248
+ return mt.includes(t);
249
+ });
250
+ return (t, g) => c.value ? (y(), X(k(gt), {
251
+ key: 0,
252
+ sections: k(r)
253
+ }, null, 8, ["sections"])) : O("", !0);
254
+ }
255
+ }), wt = (s) => {
256
+ s.slot({
257
+ type: "plugin-details",
258
+ component: yt,
259
+ order: -999
260
+ });
261
+ };
262
+ export {
263
+ wt as default
264
+ };
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ @charset "UTF-8";._item_1m2kp_1{padding:8px 16px;font-size:13px;color:var(--k-text-normal);cursor:pointer;transition:all .2s ease;white-space:nowrap;border-radius:9999px;margin:4px 0;background:transparent}._item_1m2kp_1:hover{background:#0000000f;color:var(--k-text-active)}._item_1m2kp_1._active_1m2kp_16{color:#fff;background:var(--k-color-primary);font-weight:500}._container_pbgsl_2{position:absolute;z-index:1000;width:140px;max-width:90vw;max-height:70vh;background:transparent;display:flex;flex-direction:column;font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Arial,sans-serif;-webkit-user-select:none;user-select:none;overflow:visible}@media(max-width:768px){._container_pbgsl_2{width:120px;max-height:50vh}}._container_pbgsl_2 ._header_pbgsl_21{padding:6px 10px;display:flex;justify-content:space-between;align-items:center;cursor:move;background:#ffffffd9;border-radius:20px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);margin-bottom:8px;box-shadow:0 2px 8px #00000014}._container_pbgsl_2 ._header_pbgsl_21:hover{background:#fffffff2}._container_pbgsl_2 ._header_pbgsl_21 ._move_pbgsl_36{color:var(--k-text-light);cursor:grab;transition:color .2s}._container_pbgsl_2 ._header_pbgsl_21 ._move_pbgsl_36:active{cursor:grabbing;color:var(--k-color-primary)}._container_pbgsl_2 ._header_pbgsl_21 ._toggle_pbgsl_45{cursor:pointer;color:var(--k-text-light);transition:transform .3s ease,color .2s;display:flex;align-items:center;padding:2px}._container_pbgsl_2 ._header_pbgsl_21 ._toggle_pbgsl_45:hover{color:var(--k-color-primary)}._container_pbgsl_2 ._body_pbgsl_56{overflow-y:auto;padding:4px 0;transition:max-height .3s ease,opacity .3s ease;opacity:1;scrollbar-width:none;-ms-overflow-style:none}._container_pbgsl_2 ._body_pbgsl_56::-webkit-scrollbar{display:none}._container_pbgsl_2._collapsed_pbgsl_67{max-height:40px!important}._container_pbgsl_2._collapsed_pbgsl_67 ._body_pbgsl_56{max-height:0;padding:0;opacity:0;overflow:hidden}._container_pbgsl_2._collapsed_pbgsl_67 ._toggle_pbgsl_45{transform:rotate(180deg)}