@yahaha-studio/kichi-forwarder 0.0.1-alpha.42 → 0.0.1-alpha.43
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.
- package/index.ts +51 -1
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -68,6 +68,8 @@ const LEGACY_SKILLS_CONFIG_PATH = path.join(KICHI_WORLD_DIR, "skills-config.json
|
|
|
68
68
|
const IDENTITY_PATH = path.join(KICHI_WORLD_DIR, "identity.json");
|
|
69
69
|
const RUNTIME_ALBUM_CONFIG_PATH = path.join(KICHI_WORLD_DIR, "album-config.json");
|
|
70
70
|
const MAX_NOTEBOARD_TEXT_LENGTH = 200;
|
|
71
|
+
const MAX_MESSAGE_RECEIVED_PREVIEW_WIDTH = 20;
|
|
72
|
+
const MESSAGE_RECEIVED_ELLIPSIS = "...";
|
|
71
73
|
const BUNDLED_ALBUM_CONFIG_PATH = new URL("./config/album-config.json", import.meta.url);
|
|
72
74
|
let cachedConfig: KichiRuntimeConfig | null = null;
|
|
73
75
|
let cachedConfigMtime = 0;
|
|
@@ -241,11 +243,59 @@ function syncFixedStatus(status: ActionResult): void {
|
|
|
241
243
|
});
|
|
242
244
|
}
|
|
243
245
|
|
|
246
|
+
function splitGraphemes(text: string): string[] {
|
|
247
|
+
if (typeof Intl !== "undefined" && "Segmenter" in Intl) {
|
|
248
|
+
const segmenter = new Intl.Segmenter(undefined, { granularity: "grapheme" });
|
|
249
|
+
return Array.from(segmenter.segment(text), (item) => item.segment);
|
|
250
|
+
}
|
|
251
|
+
return Array.from(text);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function getDisplayWidth(segment: string): number {
|
|
255
|
+
if (/[\u1100-\u115F\u2329\u232A\u2E80-\uA4CF\uAC00-\uD7A3\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE6F\uFF01-\uFF60\uFFE0-\uFFE6]/u.test(segment)) {
|
|
256
|
+
return 2;
|
|
257
|
+
}
|
|
258
|
+
if (/\p{Extended_Pictographic}/u.test(segment)) {
|
|
259
|
+
return 2;
|
|
260
|
+
}
|
|
261
|
+
return 1;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function getTextDisplayWidth(text: string): number {
|
|
265
|
+
return splitGraphemes(text).reduce((total, segment) => total + getDisplayWidth(segment), 0);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function truncateByDisplayWidth(text: string, maxWidth: number): string {
|
|
269
|
+
const trimmed = text.trim();
|
|
270
|
+
if (!trimmed) {
|
|
271
|
+
return "";
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const segments = splitGraphemes(trimmed);
|
|
275
|
+
const ellipsisWidth = getTextDisplayWidth(MESSAGE_RECEIVED_ELLIPSIS);
|
|
276
|
+
let currentWidth = 0;
|
|
277
|
+
let result = "";
|
|
278
|
+
|
|
279
|
+
for (const segment of segments) {
|
|
280
|
+
const nextWidth = getDisplayWidth(segment);
|
|
281
|
+
if (currentWidth + nextWidth > maxWidth) {
|
|
282
|
+
return result.trimEnd() + MESSAGE_RECEIVED_ELLIPSIS;
|
|
283
|
+
}
|
|
284
|
+
if (currentWidth + nextWidth + ellipsisWidth > maxWidth && result) {
|
|
285
|
+
return result.trimEnd() + MESSAGE_RECEIVED_ELLIPSIS;
|
|
286
|
+
}
|
|
287
|
+
result += segment;
|
|
288
|
+
currentWidth += nextWidth;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return result;
|
|
292
|
+
}
|
|
293
|
+
|
|
244
294
|
async function handleMessageReceivedHook(content: string): Promise<void> {
|
|
245
295
|
if (!service?.hasValidIdentity() || !service?.isConnected()) {
|
|
246
296
|
return;
|
|
247
297
|
}
|
|
248
|
-
const trimmed = content
|
|
298
|
+
const trimmed = truncateByDisplayWidth(content, MAX_MESSAGE_RECEIVED_PREVIEW_WIDTH);
|
|
249
299
|
service.sendHookNotify("message_received", `"${trimmed}"`);
|
|
250
300
|
}
|
|
251
301
|
|
package/package.json
CHANGED