kingkont 0.7.76 → 0.7.78

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/renderer/media.js +21 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kingkont",
3
- "version": "0.7.76",
3
+ "version": "0.7.78",
4
4
  "description": "KingKont · Chatium — нод-редактор сцен с AI-генерацией (картинки/видео/голос/SFX/музыка/текст)",
5
5
  "main": "main.js",
6
6
  "bin": {
@@ -43,7 +43,7 @@
43
43
  "postinstall": "node scripts/patch-electron-name.js"
44
44
  },
45
45
  "dependencies": {
46
- "electron": "^33.4.11"
46
+ "electron": "^38.8.6"
47
47
  },
48
48
  "devDependencies": {
49
49
  "electron-builder": "^25.1.8"
package/renderer/media.js CHANGED
@@ -1127,14 +1127,12 @@ function updateMentionPopup() {
1127
1127
  const allowed = state.genKind === 'image' ? ['image', 'text']
1128
1128
  : state.genKind === 'video' ? ['image', 'video', 'audio', 'text']
1129
1129
  : ['text', 'image', 'video', 'audio'];
1130
- // Дедуп: если у двух нод одинаковый label (basename), второй
1131
- // получает суффикс -<id4>. Это match'ит логику _scanBoardForRefs
1132
- // для chars/locs.
1133
1130
  const seen = new Set();
1134
1131
  for (const n of state.currentBoard.metadata.nodes) {
1135
1132
  if (!n.id) continue;
1136
1133
  if (!allowed.includes(n.type)) continue;
1137
- let label = (n.name || '').trim();
1134
+ const userName = (n.name || '').trim();
1135
+ let label = userName;
1138
1136
  if (!label) {
1139
1137
  label = n.file
1140
1138
  ? (n.file.split('/').pop() || '').replace(/\.[^.]+$/, '')
@@ -1145,20 +1143,11 @@ function updateMentionPopup() {
1145
1143
  seen.add(label);
1146
1144
  if (imgQuery && !label.toLowerCase().includes(imgQuery)) continue;
1147
1145
  items.push({
1148
- // key = label: красивая ссылка типа [@kitchen] для безымянной
1149
- // картинки kitchen.jpg. resolveMentions для board-нод сначала
1150
- // ищет по name; если не нашёл — gatherMediaRefs упустит,
1151
- // но мы переименуем после: для board-drill final key = label.
1152
- // Чтобы он попал в gatherMediaRefs — добавим временный n.name
1153
- // ниже. На самом деле проще: всегда insert = [@<label>], и в
1154
- // gatherMediaRefs сравнение идёт по nodeRefKey = name||id.
1155
- // Если label != name && != id — НЕ попадёт. Поэтому используем
1156
- // n.name || n.id (id как fallback) — это работает в
1157
- // resolveMentions.
1158
1146
  key: n.name || n.id,
1159
1147
  label, type: n.type, scope: 'board',
1160
1148
  file: n.file || null,
1161
1149
  boardHandle: state.currentBoard.handle,
1150
+ hasName: !!userName,
1162
1151
  });
1163
1152
  }
1164
1153
  } else {
@@ -1174,6 +1163,7 @@ function updateMentionPopup() {
1174
1163
  charName: c.name,
1175
1164
  file: img.file,
1176
1165
  boardHandle: c.handle,
1166
+ hasName: img.hasName,
1177
1167
  });
1178
1168
  }
1179
1169
  }
@@ -1190,6 +1180,7 @@ function updateMentionPopup() {
1190
1180
  locName: l.name,
1191
1181
  file: img.file,
1192
1182
  boardHandle: l.handle,
1183
+ hasName: img.hasName,
1193
1184
  });
1194
1185
  }
1195
1186
  }
@@ -1272,6 +1263,17 @@ function updateMentionPopup() {
1272
1263
  items = items.filter(s => s.key.toLowerCase().includes(query)).slice(0, 16);
1273
1264
  }
1274
1265
 
1266
+ // Сортировка: items с явно заданным именем (hasName=true) сверху,
1267
+ // basename-derived (hasName=false) — снизу. Стабильная (внутри каждой
1268
+ // группы порядок сохранён). Items без hasName поля считаются как с
1269
+ // именем (сцены/character-folders/location-folders — у них всегда есть
1270
+ // имя). На верхний уровень это не влияет — там все hasName.
1271
+ items.sort((a, b) => {
1272
+ const an = a.hasName === false ? 1 : 0;
1273
+ const bn = b.hasName === false ? 1 : 0;
1274
+ return an - bn;
1275
+ });
1276
+
1275
1277
  mentionState.open = true;
1276
1278
  mentionState.anchor = cursor - m[0].length;
1277
1279
  mentionState.items = items;
@@ -1426,7 +1428,8 @@ async function _scanBoardForRefs(itemKind, item) {
1426
1428
  const imageNodes = [];
1427
1429
  for (const n of nodes) {
1428
1430
  if (n.type !== 'image' || !n.file) continue;
1429
- let label = (n.name || '').trim();
1431
+ const userName = (n.name || '').trim();
1432
+ let label = userName;
1430
1433
  if (!label) {
1431
1434
  // basename без расширения
1432
1435
  const base = n.file.split('/').pop() || '';
@@ -1438,7 +1441,9 @@ async function _scanBoardForRefs(itemKind, item) {
1438
1441
  key = `${label}-${(n.id || '').slice(0, 4)}`;
1439
1442
  }
1440
1443
  seen.add(key);
1441
- imageNodes.push({ name: key, file: n.file, id: n.id });
1444
+ // hasName есть ли явно заданное юзером имя (n.name). По нему сортируем
1445
+ // в @-popup'е: именованные сверху, basename'ные снизу.
1446
+ imageNodes.push({ name: key, file: n.file, id: n.id, hasName: !!userName });
1442
1447
  }
1443
1448
  return { imageNodes, character, location };
1444
1449
  }