@dickpy/dsh-imagegen 1.5.1 → 1.5.3
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/README.md +13 -9
- package/docs/images/ecommerce-mode.png +0 -0
- package/docs/images/gallery-workspace.png +0 -0
- package/docs/images/image-generation-studio-three-column.png +0 -0
- package/docs/images/imagegen-overview.png +0 -0
- package/docs/images/plugin-settings.png +0 -0
- package/docs/images/prompt-template-library.png +0 -0
- package/lib/client.js +1304 -447
- package/lib/client.js.map +1 -1
- package/lib/index.js +632 -76
- package/package.json +1 -1
- package/src/client/ImageGenPanel.tsx +15 -9
- package/src/client/InspirationGallery.tsx +106 -0
- package/src/client/SettingsCard.tsx +9 -3
- package/src/client/TemplateLibrary.tsx +159 -48
- package/src/client/api.ts +41 -8
- package/src/client/helpers.ts +71 -33
- package/src/client/index.ts +59 -7
- package/src/client/inspiration.module.css +148 -0
- package/src/client/locales.ts +417 -8
- package/src/client/templates.module.css +95 -0
- package/src/client/use-language.ts +14 -0
- package/src/engine.ts +148 -0
- package/src/index.ts +23 -3
- package/src/model-catalog.ts +10 -1
- package/src/presets.ts +15 -0
- package/src/protocol.ts +81 -7
- package/src/routes.ts +124 -10
- package/src/template-favorites.ts +108 -0
- package/src/templates/canghe-cases.json +11126 -0
- package/src/templates-store.ts +179 -68
- package/docs/images/image-generation-studio-single.png +0 -0
- package/docs/images/image-generation-studio.png +0 -0
- package/docs/images/poster-features-16x9.png +0 -0
package/src/client/locales.ts
CHANGED
|
@@ -298,9 +298,13 @@ export const zh = {
|
|
|
298
298
|
'settings.overridden': '已覆盖',
|
|
299
299
|
'settings.reset': '重置',
|
|
300
300
|
'settings.invalidNumber': '请输入有效数字',
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
|
|
301
304
|
// template library
|
|
302
305
|
'templates.open': '模板库',
|
|
303
306
|
'templates.title': '提示词模板库',
|
|
307
|
+
'templates.sources': '模板库来源',
|
|
304
308
|
'templates.meta': '共 {count} 个模板 · {origin}',
|
|
305
309
|
'templates.origin.bundled': '内置快照',
|
|
306
310
|
'templates.origin.refreshed': '在线刷新',
|
|
@@ -311,21 +315,33 @@ export const zh = {
|
|
|
311
315
|
'templates.use': '使用此提示词',
|
|
312
316
|
'templates.copy': '复制提示词',
|
|
313
317
|
'templates.copied': '已复制',
|
|
314
|
-
'templates.refresh': '
|
|
318
|
+
'templates.refresh': '刷新本库',
|
|
315
319
|
'templates.refreshing': '刷新中…',
|
|
316
320
|
'templates.refreshed': '已刷新,共 {count} 个模板',
|
|
317
321
|
'templates.refreshFailed': '刷新失败:{error}',
|
|
322
|
+
'templates.favorites': '收藏',
|
|
323
|
+
'templates.favoritesHint': '只看已收藏的模板',
|
|
324
|
+
'templates.favoritesEmpty': '还没有收藏,点击模板卡片右上角的星标即可收藏',
|
|
325
|
+
'templates.favoriteAdd': '收藏此模板',
|
|
326
|
+
'templates.favoriteRemove': '取消收藏',
|
|
327
|
+
'templates.favorite': '收藏',
|
|
328
|
+
'templates.unfavorite': '已收藏',
|
|
318
329
|
'templates.cacheAll': '缓存全部图片',
|
|
319
|
-
'templates.cacheAllHint': '
|
|
330
|
+
'templates.cacheAllHint': '通过本机代理把当前模板库的全部参考图缓存到本地磁盘,之后离线也能浏览',
|
|
320
331
|
'templates.caching': '缓存中 {done}/{total}…',
|
|
321
332
|
'templates.cached': '图片已全部缓存',
|
|
322
333
|
'templates.empty': '没有匹配的模板',
|
|
323
334
|
'templates.loading': '正在加载模板库…',
|
|
324
335
|
'templates.loadFailed': '模板库加载失败:{error}',
|
|
325
336
|
'templates.retry': '重试',
|
|
326
|
-
'templates.attribution': '
|
|
327
|
-
'templates.source': '来源:
|
|
337
|
+
'templates.attribution': '模板与图片来自各来源站点,作者链接见模板详情',
|
|
338
|
+
'templates.source': '来源:{label}',
|
|
328
339
|
'templates.featured': '精选',
|
|
340
|
+
// inspiration wall (studio empty state)
|
|
341
|
+
'inspiration.title': '灵感案例',
|
|
342
|
+
'inspiration.shuffle': '随机',
|
|
343
|
+
'inspiration.shuffling': '换一批…',
|
|
344
|
+
'inspiration.useHint': '点击使用该提示词',
|
|
329
345
|
// channel management
|
|
330
346
|
'channels.title': '渠道',
|
|
331
347
|
'channels.hint': '填写各渠道的 API 地址与密钥即可使用对应模型',
|
|
@@ -662,9 +678,13 @@ export const en: Record<keyof typeof zh, string> = {
|
|
|
662
678
|
'settings.overridden': 'Overridden',
|
|
663
679
|
'settings.reset': 'Reset',
|
|
664
680
|
'settings.invalidNumber': 'Enter a valid number',
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
|
|
665
684
|
// template library
|
|
666
685
|
'templates.open': 'Templates',
|
|
667
686
|
'templates.title': 'Prompt Template Library',
|
|
687
|
+
'templates.sources': 'Template sources',
|
|
668
688
|
'templates.meta': '{count} templates · {origin}',
|
|
669
689
|
'templates.origin.bundled': 'bundled snapshot',
|
|
670
690
|
'templates.origin.refreshed': 'refreshed online',
|
|
@@ -675,21 +695,32 @@ export const en: Record<keyof typeof zh, string> = {
|
|
|
675
695
|
'templates.use': 'Use this prompt',
|
|
676
696
|
'templates.copy': 'Copy prompt',
|
|
677
697
|
'templates.copied': 'Copied',
|
|
678
|
-
'templates.refresh': 'Refresh library',
|
|
698
|
+
'templates.refresh': 'Refresh this library',
|
|
679
699
|
'templates.refreshing': 'Refreshing…',
|
|
680
700
|
'templates.refreshed': 'Refreshed — {count} templates',
|
|
681
701
|
'templates.refreshFailed': 'Refresh failed: {error}',
|
|
702
|
+
'templates.favorites': 'Favorites',
|
|
703
|
+
'templates.favoritesHint': 'Show favorited templates only',
|
|
704
|
+
'templates.favoritesEmpty': 'No favorites yet — tap the star in a card\'s top-right corner to save one',
|
|
705
|
+
'templates.favoriteAdd': 'Favorite this template',
|
|
706
|
+
'templates.favoriteRemove': 'Remove from favorites',
|
|
707
|
+
'templates.favorite': 'Favorite',
|
|
708
|
+
'templates.unfavorite': 'Favorited',
|
|
682
709
|
'templates.cacheAll': 'Cache all images',
|
|
683
|
-
'templates.cacheAllHint': 'Mirror every reference image to local disk through the host proxy, for offline browsing',
|
|
710
|
+
'templates.cacheAllHint': 'Mirror every reference image of the current library to local disk through the host proxy, for offline browsing',
|
|
684
711
|
'templates.caching': 'Caching {done}/{total}…',
|
|
685
712
|
'templates.cached': 'All images cached',
|
|
686
713
|
'templates.empty': 'No matching templates',
|
|
687
714
|
'templates.loading': 'Loading the template library…',
|
|
688
715
|
'templates.loadFailed': 'Failed to load the library: {error}',
|
|
689
716
|
'templates.retry': 'Retry',
|
|
690
|
-
'templates.attribution': 'Templates and images come from
|
|
691
|
-
'templates.source': 'Source:
|
|
717
|
+
'templates.attribution': 'Templates and images come from each source site; author links are on each template',
|
|
718
|
+
'templates.source': 'Source: {label}',
|
|
692
719
|
'templates.featured': 'Featured',
|
|
720
|
+
// inspiration wall (studio empty state)
|
|
721
|
+
'inspiration.title': 'Inspiration', 'inspiration.shuffle': 'Shuffle',
|
|
722
|
+
'inspiration.shuffling': 'Shuffling…',
|
|
723
|
+
'inspiration.useHint': 'Click to use this prompt',
|
|
693
724
|
// channel management
|
|
694
725
|
'channels.title': 'Channels',
|
|
695
726
|
'channels.hint': 'Fill in each channel\'s API URL and key to use its models',
|
|
@@ -744,3 +775,381 @@ export const en: Record<keyof typeof zh, string> = {
|
|
|
744
775
|
|
|
745
776
|
/** Locale key union. */
|
|
746
777
|
export type ImageGenKey = keyof typeof zh
|
|
778
|
+
|
|
779
|
+
/** Russian mirror of every key (полный словарь интерфейса). */
|
|
780
|
+
export const ru: Record<keyof typeof zh, string> = {
|
|
781
|
+
'entry.label': 'ИИ-генерация',
|
|
782
|
+
'entry.tooltip': 'Панель ИИ-генерации изображений (gpt-image-2 / glm-image / grok-imagine-image / nanobanana / seedream)',
|
|
783
|
+
'entry.newSession': 'Новая сессия',
|
|
784
|
+
'entry.newSessionTooltip': 'Создать новую сессию DSH',
|
|
785
|
+
'entry.image': 'Генерация',
|
|
786
|
+
'panel.title': 'ИИ-генерация изображений',
|
|
787
|
+
'panel.githubTip': 'Понравился плагин или есть идеи? Поставьте звезду или откройте issue на GitHub!',
|
|
788
|
+
'conversation.add': 'В диалог',
|
|
789
|
+
'conversation.adding': 'Добавляем…',
|
|
790
|
+
'conversation.added': 'Изображение добавлено в текущий диалог',
|
|
791
|
+
'conversation.addHint': 'После добавления можно править через /edit_image; команда использует модель плагина',
|
|
792
|
+
'conversation.noSession': 'Сначала откройте сессию, затем добавьте изображение',
|
|
793
|
+
'conversation.unavailable': 'Текущая сессия недоступна',
|
|
794
|
+
'conversation.busy': 'Диалог отправляет сообщение, попробуйте позже',
|
|
795
|
+
'mode.text': 'Из текста',
|
|
796
|
+
'mode.edit': 'Из изображения',
|
|
797
|
+
'workspace.label': 'Режим работы',
|
|
798
|
+
'workspace.normal': 'Генерация',
|
|
799
|
+
'workspace.ecommerce': 'E-commerce',
|
|
800
|
+
'chat.expand': 'Показать диалог',
|
|
801
|
+
'chat.collapse': 'Скрыть диалог',
|
|
802
|
+
'chat.toggle': 'Диалог',
|
|
803
|
+
'config.resizeHint': 'Потяните, чтобы изменить ширину панели параметров',
|
|
804
|
+
'ecommerce.generation': 'Параметры генерации',
|
|
805
|
+
'ecommerce.title': 'Режим e-commerce',
|
|
806
|
+
'ecommerce.badge': 'Превью',
|
|
807
|
+
'ecommerce.short': 'E-com',
|
|
808
|
+
'ecommerce.anchorPending': 'Главное изображение готово, остальные генерируются по нему для единого стиля…',
|
|
809
|
+
'ecommerce.anchorFailed': 'Не удалось создать главное изображение, остальные приостановлены. Повторите главное (или всю группу) и продолжите.',
|
|
810
|
+
'ecommerce.anchorNote': 'Якорная генерация: сначала главное изображение, остальные создаются по нему для единого стиля',
|
|
811
|
+
'ecommerce.noAssetWarn': 'Товар не загружен: главное изображение будет создано по описанию и станет якорем; загрузите фото товара для большей точности',
|
|
812
|
+
'ecommerce.product': 'Товар',
|
|
813
|
+
'ecommerce.productName': 'Название товара (обязательно)',
|
|
814
|
+
'ecommerce.projectName': 'Название проекта (необязательно)',
|
|
815
|
+
'ecommerce.constraints': 'Преимущества и ограничения',
|
|
816
|
+
'ecommerce.sellingPoints': 'Преимущества товара, например: водостойкость / большая вместимость / компактность',
|
|
817
|
+
'ecommerce.protectedFeatures': 'Что обязательно сохранить: цвет, логотип, текст упаковки, конструкцию',
|
|
818
|
+
'ecommerce.styleHint': 'Стиль, например: премиальный / реалистичный / естественный свет',
|
|
819
|
+
'ecommerce.setStructure': 'Структура комплекта',
|
|
820
|
+
'ecommerce.preview': 'Создать превью комплекта',
|
|
821
|
+
'ecommerce.planTitle': 'Будет сгенерировано изображений: {count}',
|
|
822
|
+
'ecommerce.planSlot': '{count} шт. · {description}',
|
|
823
|
+
'ecommerce.confirm': 'Сгенерировать весь комплект',
|
|
824
|
+
'ecommerce.uploadRef': 'Материалы товара (необязательно, до 4 шт.: товар / упаковка / детали / стиль)',
|
|
825
|
+
'ecommerce.uploadShort': 'Загрузить материалы',
|
|
826
|
+
'ecommerce.sellingTitle': 'Преимущества товара',
|
|
827
|
+
'ecommerce.advanced': 'Дополнительно (проект / площадка / ограничения)',
|
|
828
|
+
'ecommerce.params': 'Параметры',
|
|
829
|
+
'ecommerce.platformLabel': 'Площадка',
|
|
830
|
+
'ecommerce.languageLabel': 'Язык текста',
|
|
831
|
+
'ecommerce.ratioLabel': 'Пропорции',
|
|
832
|
+
'ecommerce.categoryLabel': 'Категория',
|
|
833
|
+
'ecommerce.multiSelect': 'Можно выбрать несколько',
|
|
834
|
+
'ecommerce.countHint': 'Нажмите, чтобы изменить количество (1-4)',
|
|
835
|
+
'ecommerce.refSettings': 'Настройки референсов (необязательно)',
|
|
836
|
+
'ecommerce.styleTitle': 'Стиль / дополнения',
|
|
837
|
+
'ecommerce.protectedLabel': 'Обязательно сохранить (необязательно)',
|
|
838
|
+
'ecommerce.assetsFull': 'Не более 4 материалов',
|
|
839
|
+
'ecommerce.refSelect': 'Референс для этого назначения',
|
|
840
|
+
'ecommerce.refNone': 'Без референса',
|
|
841
|
+
'ecommerce.role.product': 'Товар',
|
|
842
|
+
'ecommerce.role.packaging': 'Упаковка',
|
|
843
|
+
'ecommerce.role.detail': 'Детали/ракурс',
|
|
844
|
+
'ecommerce.role.style': 'Стиль',
|
|
845
|
+
'ecommerce.footerReady': 'Будет сгенерировано {count} изображений',
|
|
846
|
+
'ecommerce.footerEmpty': 'Выберите структуру комплекта',
|
|
847
|
+
'ecommerce.results.title': 'Результаты комплекта',
|
|
848
|
+
'ecommerce.results.progress': '{done}/{total} готово',
|
|
849
|
+
'ecommerce.results.failed': '{count} с ошибкой',
|
|
850
|
+
'ecommerce.results.empty': 'После запуска генерации здесь появятся статус и результат каждого изображения',
|
|
851
|
+
'ecommerce.results.regenerate': 'Сгенерировать заново',
|
|
852
|
+
'ecommerce.results.export': 'Экспорт списка',
|
|
853
|
+
'ecommerce.results.newProduct': 'Новый товар',
|
|
854
|
+
'prompt.placeholder': 'Опишите желаемое изображение, например: рыжий кот в шлеме космонавта смотрит в телескоп на Луне, акварель, мягкий свет…',
|
|
855
|
+
'prompt.required': 'Введите промпт',
|
|
856
|
+
'prompt.count': '{count}',
|
|
857
|
+
'prompt.enhance': 'Улучш.',
|
|
858
|
+
'prompt.enhancing': 'Улучшаем…',
|
|
859
|
+
'prompt.enhanceHint': 'Развернуть краткий промпт через настроенную диалоговую модель',
|
|
860
|
+
'prompt.configTitle': 'Сначала настройте модель улучшения промптов',
|
|
861
|
+
'prompt.configHint': 'Настройки открыты. Перейдите в «Плагины → ИИ-генерация», укажите или переиспользуйте API-адрес и ключ, выберите диалоговую модель и сохраните.',
|
|
862
|
+
'tasks.title': 'Задачи генерации',
|
|
863
|
+
'tasks.queued': 'В очереди',
|
|
864
|
+
'tasks.running': 'Генерация',
|
|
865
|
+
'tasks.completed': 'Готово',
|
|
866
|
+
'tasks.failed': 'Ошибка',
|
|
867
|
+
'tasks.cancelled': 'Отменено',
|
|
868
|
+
'tasks.cancel': 'Отменить',
|
|
869
|
+
'tasks.retry': 'Повторить',
|
|
870
|
+
'params.size': 'Размер',
|
|
871
|
+
'params.quality': 'Чёткость',
|
|
872
|
+
'params.count': 'Количество',
|
|
873
|
+
'params.detail': 'Детализация',
|
|
874
|
+
'size.auto': 'Авто',
|
|
875
|
+
'size.square': '1:1 квадрат',
|
|
876
|
+
'size.portrait34': '3:4 верт.',
|
|
877
|
+
'size.landscape43': '4:3 гориз.',
|
|
878
|
+
'size.portrait916': '9:16 верт.',
|
|
879
|
+
'size.portrait23': '2:3 верт.',
|
|
880
|
+
'size.landscape32': '3:2 гориз.',
|
|
881
|
+
'size.wide169': '16:9 шир.',
|
|
882
|
+
'size.ultrawide21': '21:9 ультрашир.',
|
|
883
|
+
'quality.auto': 'Авто',
|
|
884
|
+
'quality.1k': '1K',
|
|
885
|
+
'quality.2k': '2K',
|
|
886
|
+
'quality.4k': '4K',
|
|
887
|
+
'count.one': '1 шт.',
|
|
888
|
+
'count.two': '2 шт.',
|
|
889
|
+
'count.three': '3 шт.',
|
|
890
|
+
'count.four': '4 шт.',
|
|
891
|
+
'detail.auto': 'Авто',
|
|
892
|
+
'detail.standard': 'Стандарт',
|
|
893
|
+
'detail.high': 'Высокая',
|
|
894
|
+
'detail.hint': 'Сквозной параметр, поддерживают некоторые шлюзы gpt-image-2; для официального API оставьте «Авто»',
|
|
895
|
+
'model.label': 'Модель',
|
|
896
|
+
'model.noEditModels': 'В текущем режиме нет доступных моделей',
|
|
897
|
+
'compare.enable': 'Сравнение моделей',
|
|
898
|
+
'compare.models': 'Модели для сравнения',
|
|
899
|
+
'compare.title': 'Сравнение результатов моделей',
|
|
900
|
+
'compare.fullscreen': 'Полноэкранное сравнение',
|
|
901
|
+
'compare.selectRequired': 'Выберите хотя бы одну модель для сравнения',
|
|
902
|
+
'generate': 'Сгенерировать',
|
|
903
|
+
'generating': 'Генерация…',
|
|
904
|
+
'edit.upload': 'Нажмите или перетащите референс',
|
|
905
|
+
'edit.uploadHint': 'PNG / JPG / WEBP, до 10 МБ',
|
|
906
|
+
'edit.change': 'Заменить изображение',
|
|
907
|
+
'edit.remove': 'Убрать',
|
|
908
|
+
'edit.required': 'Сначала загрузите референс',
|
|
909
|
+
'canvas.emptyTitle': 'Начните творить',
|
|
910
|
+
'canvas.emptyHint': 'Введите промпт слева и нажмите «Сгенерировать» — результат появится здесь',
|
|
911
|
+
'canvas.new': 'Новая генерация',
|
|
912
|
+
'canvas.newHint': 'Начать новую генерацию и очистить просмотр',
|
|
913
|
+
'canvas.error': 'Ошибка генерации: {error}',
|
|
914
|
+
'canvas.submitting': 'Ставим в очередь…',
|
|
915
|
+
'canvas.queued': 'Задача в очереди',
|
|
916
|
+
'canvas.queueHint': 'Сейчас ожидают {count} задач',
|
|
917
|
+
'canvas.generating': 'Генерируем изображение…',
|
|
918
|
+
'canvas.elapsed': 'Прошло {seconds} с',
|
|
919
|
+
'canvas.images': 'Сгенерировано: {count}',
|
|
920
|
+
'download': 'Скачать',
|
|
921
|
+
'revisedPrompt': 'Улучшенный промпт: {prompt}',
|
|
922
|
+
'history.title': 'История',
|
|
923
|
+
'history.empty': 'Истории пока нет — созданные изображения появятся здесь',
|
|
924
|
+
'history.clear': 'Очистить',
|
|
925
|
+
'history.clearConfirm': 'Очистить всю историю? Действие необратимо.',
|
|
926
|
+
'history.restore': 'Восстановить',
|
|
927
|
+
'history.delete': 'Удалить',
|
|
928
|
+
'history.images': 'шт.',
|
|
929
|
+
'history.viewing': 'История · {time}',
|
|
930
|
+
'history.search': 'Поиск по промптам и моделям…',
|
|
931
|
+
'history.model': 'Фильтр по модели',
|
|
932
|
+
'history.ratio': 'Фильтр по пропорциям',
|
|
933
|
+
'history.allModels': 'Все модели',
|
|
934
|
+
'history.allRatios': 'Все пропорции',
|
|
935
|
+
'gallery.title': 'Галерея',
|
|
936
|
+
'gallery.categories': 'Категории',
|
|
937
|
+
'gallery.all': 'Все работы',
|
|
938
|
+
'gallery.gpt': 'gpt-image-2',
|
|
939
|
+
'gallery.grok': 'grok-imagine-image',
|
|
940
|
+
'gallery.ratio': 'Пропорции',
|
|
941
|
+
'gallery.tags': 'Метки',
|
|
942
|
+
'gallery.filterHint': 'Фильтр галереи по режиму, модели и пропорциям',
|
|
943
|
+
'gallery.count': '· всего {count}',
|
|
944
|
+
'gallery.viewMode': 'Вид',
|
|
945
|
+
'gallery.masonry': 'Плитка',
|
|
946
|
+
'gallery.grid': 'Сетка',
|
|
947
|
+
'gallery.sort': 'Сортировка',
|
|
948
|
+
'gallery.newest': 'Сначала новые',
|
|
949
|
+
'gallery.oldest': 'Сначала старые',
|
|
950
|
+
'gallery.untitled': 'Без названия',
|
|
951
|
+
'gallery.search': 'Поиск по работам и моделям…',
|
|
952
|
+
'gallery.tagsPlaceholder': 'Метки через запятую',
|
|
953
|
+
'gallery.tagsApply': 'Добавить метки',
|
|
954
|
+
'gallery.editTags': 'Править метки',
|
|
955
|
+
'gallery.tagsEditShort': 'Правка',
|
|
956
|
+
'gallery.tagsSave': 'Сохранить',
|
|
957
|
+
'gallery.tagsCancel': 'Отмена',
|
|
958
|
+
'gallery.selected': 'Выбрано: {count}',
|
|
959
|
+
'gallery.selectionDone': 'Завершить выбор',
|
|
960
|
+
'gallery.selectionClear': 'Снять выбор',
|
|
961
|
+
'gallery.downloadSelected': 'Скачать выбранные',
|
|
962
|
+
'gallery.exportJson': 'Экспорт JSON',
|
|
963
|
+
'gallery.select': 'Выбрать работы',
|
|
964
|
+
'gallery.add': 'В галерею',
|
|
965
|
+
'gallery.added': 'Добавлено в галерею',
|
|
966
|
+
'gallery.already': 'Уже в галерее',
|
|
967
|
+
'gallery.delete': 'Убрать из галереи',
|
|
968
|
+
'gallery.clear': 'Очистить галерею',
|
|
969
|
+
'gallery.clearConfirm': 'Очистить всю галерею? Действие необратимо.',
|
|
970
|
+
'gallery.empty': 'Галерея пуста — добавьте понравившиеся изображения',
|
|
971
|
+
'gallery.viewing': 'Галерея · {time}',
|
|
972
|
+
'preview.title': 'Просмотр изображения',
|
|
973
|
+
'preview.open': 'Открыть просмотр',
|
|
974
|
+
'preview.close': 'Закрыть',
|
|
975
|
+
'preview.prev': 'Назад',
|
|
976
|
+
'preview.next': 'Вперёд',
|
|
977
|
+
'preview.index': '{index} / {total}',
|
|
978
|
+
'preview.zoomControls': 'Управление масштабом',
|
|
979
|
+
'preview.zoomIn': 'Увеличить',
|
|
980
|
+
'preview.zoomOut': 'Уменьшить',
|
|
981
|
+
'preview.zoomReset': 'Сбросить масштаб',
|
|
982
|
+
'preview.zoomLevel': '{percent}%',
|
|
983
|
+
'preview.copyPrompt': 'Копировать промпт',
|
|
984
|
+
'preview.copied': 'Скопировано',
|
|
985
|
+
'preview.addToEdit': 'В режим img2img',
|
|
986
|
+
'config.missing': 'API не настроен: откройте «Настройки → Плагины → Настраиваемые» и заполните api_url и api_key для ИИ-генерации.',
|
|
987
|
+
'config.generationTitle': 'Сначала настройте API генерации',
|
|
988
|
+
'config.generationHint': 'Открыты «Настройки → Плагины → ИИ-генерация». Укажите адрес и ключ API генерации, сохраните — и можно творить.',
|
|
989
|
+
'config.enhancementTitle': 'Сначала настройте модель улучшения промптов',
|
|
990
|
+
'config.enhancementHint': 'Открыты «Настройки → Плагины → ИИ-генерация». Укажите или переиспользуйте адрес и ключ диалогового API, выберите модель и сохраните.',
|
|
991
|
+
'config.disabledTitle': 'Плагин ИИ-генерации отключён',
|
|
992
|
+
'config.disabledHint': 'Открыты «Настройки → Плагины → ИИ-генерация». Включите плагин — и генерация заработает.',
|
|
993
|
+
'config.configured': 'Подключено: {url}',
|
|
994
|
+
'config.disabled': 'Плагин отключён — включите его в настройках.',
|
|
995
|
+
'connection.connected': 'Подключено',
|
|
996
|
+
'connection.disconnected': 'Нет подключения',
|
|
997
|
+
'panel.collapseConfig': 'Свернуть параметры',
|
|
998
|
+
'panel.expandConfig': 'Развернуть параметры',
|
|
999
|
+
'update.available': 'Доступна новая версия: {version}',
|
|
1000
|
+
'update.install': 'Обновить онлайн',
|
|
1001
|
+
'update.installing': 'Обновляем…',
|
|
1002
|
+
'update.success': 'Обновлено до {version}, перезапустите DSH',
|
|
1003
|
+
'update.failed': 'Не удалось обновить, попробуйте ещё раз',
|
|
1004
|
+
'update.release': 'Открыть релиз',
|
|
1005
|
+
'settings.title': 'ИИ-генерация (dsh-imagegen)',
|
|
1006
|
+
'settings.description': 'Адрес и ключ API генерации изображений',
|
|
1007
|
+
'settings.currentVersion': 'Текущая версия',
|
|
1008
|
+
'settings.apiUrl': 'Адрес API (api_url)',
|
|
1009
|
+
'settings.apiUrlHint': 'База OpenAI-совместимого API, например https://api.openai.com/v1; /images/generations и /images/edits дописываются автоматически',
|
|
1010
|
+
'settings.apiKey': 'Ключ API (api_key)',
|
|
1011
|
+
'settings.apiKeyHint': 'Bearer-ключ хранится открыто в локальном документе настроек; интерфейс показывает лишь факт его наличия',
|
|
1012
|
+
'settings.apiKeySet': 'Ключ сохранён; введите новый, чтобы заменить, или нажмите «Очистить»',
|
|
1013
|
+
'settings.apiKeyClear': 'Очистить',
|
|
1014
|
+
'settings.imageModelsTitle': 'Модели генерации',
|
|
1015
|
+
'settings.imageModelsHint': 'После сохранения адреса и ключа будут найдены кандидаты; выбирайте только те, что реально умеют генерировать изображения.',
|
|
1016
|
+
'settings.imageModels': 'Разрешённые модели генерации',
|
|
1017
|
+
'settings.imageModelsManualHint': 'По одной модели в строке; можно заполнить вручную, если API не отдаёт /models. Панель и агент используют только этот список.',
|
|
1018
|
+
'settings.imageModelsFetch': 'Найти модели',
|
|
1019
|
+
'settings.imageModelsLoading': 'Ищем…',
|
|
1020
|
+
'settings.imageModelsCandidates': 'Найденные кандидаты (отметьте и сохраните)',
|
|
1021
|
+
'settings.addModel': '+ Добавить вручную',
|
|
1022
|
+
'settings.cancelAddModel': 'Скрыть добавление',
|
|
1023
|
+
'settings.addModelPlaceholder': 'Имя модели, например qwen-image',
|
|
1024
|
+
'settings.addModelConfirm': 'Добавить',
|
|
1025
|
+
'settings.removeModel': 'Удалить модель',
|
|
1026
|
+
'settings.optional': 'необязательно',
|
|
1027
|
+
'settings.moreOptions': 'Дополнительно',
|
|
1028
|
+
'settings.promptEnhanceTitle': 'Модель улучшения промптов',
|
|
1029
|
+
'settings.promptEnhanceHint': 'Разворачивает краткое описание в полноценный промпт; пустые адрес и ключ наследуют настройки генерации.',
|
|
1030
|
+
'settings.promptApiUrl': 'Адрес диалогового API (необязательно)',
|
|
1031
|
+
'settings.promptApiUrlHint': 'OpenAI-совместимая база; если пусто — используется адрес API генерации.',
|
|
1032
|
+
'settings.promptApiKey': 'Ключ диалогового API (необязательно)',
|
|
1033
|
+
'settings.promptApiKeyHint': 'Если пусто — используется ключ API генерации.',
|
|
1034
|
+
'settings.promptModel': 'Диалоговая модель',
|
|
1035
|
+
'settings.promptModelHint': 'Выберите или впишите модель с поддержкой /chat/completions.',
|
|
1036
|
+
'settings.promptModelDetectionHint': 'По умолчанию используется API генерации; после поиска просто выберите модель.',
|
|
1037
|
+
'settings.promptModelsFetch': 'Получить модели',
|
|
1038
|
+
'settings.promptModelsLoading': 'Получаем…',
|
|
1039
|
+
'settings.promptModelsSelect': 'Выберите модель',
|
|
1040
|
+
'settings.promptModelsCandidates': 'Найденные диалоговые модели',
|
|
1041
|
+
'settings.addPromptModelPlaceholder': 'Имя диалоговой модели, например gpt-4.1-mini',
|
|
1042
|
+
'settings.promptApiAdvanced': 'Отдельный диалоговый API (необязательно)',
|
|
1043
|
+
'settings.announceToAgent': 'Оповещать агентов о плагине',
|
|
1044
|
+
'settings.announceToAgentHint': 'Включено — возможности плагина добавляются в системный промпт каждого агента',
|
|
1045
|
+
'settings.allowAgentImageGeneration': 'Разрешить агентам генерацию',
|
|
1046
|
+
'settings.allowAgentImageGenerationHint': 'Включено по умолчанию. Выключено — агенты не могут создавать, смотреть или отменять задачи; боковая панель работает.',
|
|
1047
|
+
'settings.enabled': 'Включить плагин',
|
|
1048
|
+
'settings.enabledHint': 'Выключено — панель генерации недоступна (карточка настроек работает всегда)',
|
|
1049
|
+
'settings.save': 'Сохранить',
|
|
1050
|
+
'settings.saving': 'Сохраняем…',
|
|
1051
|
+
'settings.discard': 'Отменить правки',
|
|
1052
|
+
'settings.unsaved': 'Есть несохранённые правки',
|
|
1053
|
+
'settings.saveFailed': 'Не удалось сохранить, попробуйте ещё раз',
|
|
1054
|
+
'settings.readOnly': 'Документ настроек сейчас только для чтения, сохранить нельзя.',
|
|
1055
|
+
'settings.notExposed': 'Пространство настроек недоступно: этот деплой не предоставляет сервис настроек плагина.',
|
|
1056
|
+
'settings.expand': 'Развернуть',
|
|
1057
|
+
'settings.collapse': 'Свернуть',
|
|
1058
|
+
'settings.inherit': 'Наследовать',
|
|
1059
|
+
'settings.on': 'Вкл',
|
|
1060
|
+
'settings.off': 'Выкл',
|
|
1061
|
+
'settings.overridden': 'Переопределено',
|
|
1062
|
+
'settings.reset': 'Сбросить',
|
|
1063
|
+
'settings.invalidNumber': 'Введите корректное число',
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
'templates.open': 'Шаблоны',
|
|
1068
|
+
'templates.title': 'Библиотека промпт-шаблонов',
|
|
1069
|
+
'templates.sources': 'Источники шаблонов',
|
|
1070
|
+
'templates.meta': 'Всего шаблонов: {count} · {origin}',
|
|
1071
|
+
'templates.origin.bundled': 'встроенный снимок',
|
|
1072
|
+
'templates.origin.refreshed': 'обновлено онлайн',
|
|
1073
|
+
'templates.search': 'Поиск по названиям и промптам…',
|
|
1074
|
+
'templates.all': 'Все',
|
|
1075
|
+
'templates.close': 'Закрыть',
|
|
1076
|
+
'templates.back': 'К списку',
|
|
1077
|
+
'templates.use': 'Использовать промпт',
|
|
1078
|
+
'templates.copy': 'Копировать промпт',
|
|
1079
|
+
'templates.copied': 'Скопировано',
|
|
1080
|
+
'templates.refresh': 'Обновить библиотеку',
|
|
1081
|
+
'templates.refreshing': 'Обновляем…',
|
|
1082
|
+
'templates.refreshed': 'Обновлено, шаблонов: {count}',
|
|
1083
|
+
'templates.refreshFailed': 'Ошибка обновления: {error}',
|
|
1084
|
+
'templates.favorites': 'Избранное',
|
|
1085
|
+
'templates.favoritesHint': 'Показать только избранные шаблоны',
|
|
1086
|
+
'templates.favoritesEmpty': 'Пока пусто — нажмите звёздочку в углу карточки, чтобы сохранить шаблон',
|
|
1087
|
+
'templates.favoriteAdd': 'Добавить в избранное',
|
|
1088
|
+
'templates.favoriteRemove': 'Убрать из избранного',
|
|
1089
|
+
'templates.favorite': 'В избранное',
|
|
1090
|
+
'templates.unfavorite': 'В избранном',
|
|
1091
|
+
'templates.cacheAll': 'Кэшировать все картинки',
|
|
1092
|
+
'templates.cacheAllHint': 'Через локальный прокси сохранит все референсы этой библиотеки на диск — дальше доступно офлайн',
|
|
1093
|
+
'templates.caching': 'Кэшируем {done}/{total}…',
|
|
1094
|
+
'templates.cached': 'Все картинки закэшированы',
|
|
1095
|
+
'templates.empty': 'Нет подходящих шаблонов',
|
|
1096
|
+
'templates.loading': 'Загружаем библиотеку…',
|
|
1097
|
+
'templates.loadFailed': 'Не удалось загрузить библиотеку: {error}',
|
|
1098
|
+
'templates.retry': 'Повторить',
|
|
1099
|
+
'templates.attribution': 'Шаблоны и изображения принадлежат сайтам-источникам; ссылки на авторов — в карточках',
|
|
1100
|
+
'templates.source': 'Источник: {label}',
|
|
1101
|
+
'templates.featured': 'Выбор редакции',
|
|
1102
|
+
'inspiration.title': 'Вдохновение',
|
|
1103
|
+
'inspiration.shuffle': 'Другие',
|
|
1104
|
+
'inspiration.shuffling': 'Подбираем…',
|
|
1105
|
+
'inspiration.useHint': 'Нажмите, чтобы использовать промпт',
|
|
1106
|
+
'channels.title': 'Каналы',
|
|
1107
|
+
'channels.hint': 'Укажите адрес и ключ API каждого канала — и модели станут доступны',
|
|
1108
|
+
'channels.empty': 'Каналов пока нет — добавьте кнопкой ниже',
|
|
1109
|
+
'channels.addProvider': 'Добавить провайдера',
|
|
1110
|
+
'channels.addCustom': 'Добавить свой канал',
|
|
1111
|
+
'channels.untitled': 'Канал без названия',
|
|
1112
|
+
'channels.keySet': 'Ключ задан',
|
|
1113
|
+
'channels.keyMissing': 'Ключ не задан',
|
|
1114
|
+
'channels.modelCount': 'Моделей: {n}',
|
|
1115
|
+
'channels.noModels': 'Модели не настроены',
|
|
1116
|
+
'channels.defaultLabel': 'По умолчанию',
|
|
1117
|
+
'channels.statusReady': 'Готов',
|
|
1118
|
+
'channels.statusIncomplete': 'Настройка не завершена',
|
|
1119
|
+
'channels.edit': 'Править',
|
|
1120
|
+
'channels.delete': 'Удалить',
|
|
1121
|
+
'channels.deleteConfirmTitle': 'Удалить канал «{name}»? Ключ канала будет удалён; история и галерея сохранятся.',
|
|
1122
|
+
'channels.confirm': 'Удалить',
|
|
1123
|
+
'channels.cancel': 'Отмена',
|
|
1124
|
+
'channels.editorTitle': 'Канал',
|
|
1125
|
+
'channels.editorSaveNote': 'Изменения вступят в силу после «Сохранить» внизу карточки',
|
|
1126
|
+
'channels.displayName': 'Название',
|
|
1127
|
+
'channels.apiUrl': 'Адрес API',
|
|
1128
|
+
'channels.apiKey': 'Ключ API',
|
|
1129
|
+
'channels.keyReplaceHint': 'Задан — введите новый, чтобы заменить',
|
|
1130
|
+
'channels.keyMissingHint': 'Введите ключ',
|
|
1131
|
+
'channels.keyClear': 'Очистить ключ',
|
|
1132
|
+
'channels.modelCatalogTitle': 'Каталог моделей',
|
|
1133
|
+
'channels.noModelsHint': 'Моделей пока нет: нажмите «Найти» для списка кандидатов или добавьте вручную; псевдоним по умолчанию равен id модели и его можно менять.',
|
|
1134
|
+
'channels.detect': 'Найти снова',
|
|
1135
|
+
'channels.detecting': 'Ищем…',
|
|
1136
|
+
'channels.detectSuccess': 'Связь есть ✓ · кандидатов: {n}',
|
|
1137
|
+
'channels.detectFailed': 'Ошибка поиска: {error}',
|
|
1138
|
+
'channels.detectOk': 'API отвечает',
|
|
1139
|
+
'channels.modelAliasLabel': 'Псевдоним (отображается)',
|
|
1140
|
+
'channels.modelIdLabel': 'id модели у провайдера',
|
|
1141
|
+
'channels.generated': 'Сгенерировано: {n}',
|
|
1142
|
+
'channels.unknownProtocol': 'Протокол неизвестен — пробуем универсальный OpenAI',
|
|
1143
|
+
'channels.removeModel': 'Удалить модель',
|
|
1144
|
+
'channels.manualAddPlaceholder': 'id модели, например qwen-image',
|
|
1145
|
+
'channels.addModelConfirm': 'Добавить',
|
|
1146
|
+
'channels.copyFrom': 'Скопировать из канала…',
|
|
1147
|
+
'channels.copyApply': 'Копировать',
|
|
1148
|
+
'channels.candidatesTitle': 'Кандидаты (нажмите, чтобы добавить)',
|
|
1149
|
+
'channels.deleteThisChannel': 'Удалить этот канал',
|
|
1150
|
+
'channels.setDefault': 'Сделать каналом по умолчанию',
|
|
1151
|
+
'channels.presetPickerTitle': 'Добавить провайдера',
|
|
1152
|
+
'channels.presetPickerHint': 'Выберите встроенного провайдера — останется ввести только ключ API',
|
|
1153
|
+
'channels.presetCustomHint': 'Свой адрес, ключ и каталог моделей',
|
|
1154
|
+
'channels.presetLoadFailed': 'Не удалось загрузить провайдеров: {error}',
|
|
1155
|
+
}
|
|
@@ -92,6 +92,60 @@
|
|
|
92
92
|
color: var(--dsw-alias-label-primary);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/* --- source tabs --------------------------------------------------------- */
|
|
96
|
+
|
|
97
|
+
.sourceTabs {
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
gap: 6px;
|
|
101
|
+
padding: 0 18px 10px;
|
|
102
|
+
border-bottom: 1px solid var(--dsw-alias-border-l1);
|
|
103
|
+
flex: none;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.sourceTab {
|
|
107
|
+
display: inline-flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
gap: 6px;
|
|
110
|
+
height: 30px;
|
|
111
|
+
padding: 0 14px;
|
|
112
|
+
border: 1px solid transparent;
|
|
113
|
+
border-radius: 9px 9px 0 0;
|
|
114
|
+
border-bottom: none;
|
|
115
|
+
background: transparent;
|
|
116
|
+
color: var(--dsw-alias-label-secondary);
|
|
117
|
+
font-size: 13px;
|
|
118
|
+
font-weight: 600;
|
|
119
|
+
font-family: inherit;
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
white-space: nowrap;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.sourceTab:hover {
|
|
125
|
+
color: var(--dsw-alias-label-primary);
|
|
126
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.sourceTab[data-active] {
|
|
130
|
+
border-color: var(--dsw-alias-border-l1);
|
|
131
|
+
border-radius: 9px;
|
|
132
|
+
background: var(--dsw-alias-bg-layer-1);
|
|
133
|
+
color: var(--dsw-alias-brand-primary);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.sourceTabCount {
|
|
137
|
+
padding: 0 6px;
|
|
138
|
+
border-radius: 999px;
|
|
139
|
+
background: var(--dsw-alias-bg-layer-2);
|
|
140
|
+
color: var(--dsw-alias-label-tertiary);
|
|
141
|
+
font-size: 11px;
|
|
142
|
+
font-weight: 500;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.sourceTab[data-active] .sourceTabCount {
|
|
146
|
+
color: var(--dsw-alias-label-secondary);
|
|
147
|
+
}
|
|
148
|
+
|
|
95
149
|
/* --- toolbar ----------------------------------------------------------- */
|
|
96
150
|
|
|
97
151
|
.toolbar {
|
|
@@ -263,6 +317,47 @@
|
|
|
263
317
|
font-weight: 600;
|
|
264
318
|
}
|
|
265
319
|
|
|
320
|
+
.favStar {
|
|
321
|
+
position: absolute;
|
|
322
|
+
top: 6px;
|
|
323
|
+
right: 6px;
|
|
324
|
+
display: inline-flex;
|
|
325
|
+
align-items: center;
|
|
326
|
+
justify-content: center;
|
|
327
|
+
width: 26px;
|
|
328
|
+
height: 26px;
|
|
329
|
+
padding: 0;
|
|
330
|
+
border: none;
|
|
331
|
+
border-radius: 8px;
|
|
332
|
+
background: rgba(0, 0, 0, 0.35);
|
|
333
|
+
color: rgba(255, 255, 255, 0.85);
|
|
334
|
+
cursor: pointer;
|
|
335
|
+
opacity: 0;
|
|
336
|
+
transition: opacity 0.15s ease;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.card:hover .favStar,
|
|
340
|
+
.favStar:focus-visible,
|
|
341
|
+
.favStar[data-active] {
|
|
342
|
+
opacity: 1;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.favStar:hover {
|
|
346
|
+
background: rgba(0, 0, 0, 0.55);
|
|
347
|
+
color: #ffffff;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.favStar[data-active] {
|
|
351
|
+
color: #ffb020;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/* Touch shells have no hover: keep the star reachable. */
|
|
355
|
+
@media (hover: none) {
|
|
356
|
+
.favStar {
|
|
357
|
+
opacity: 1;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
266
361
|
.cardBody {
|
|
267
362
|
display: flex;
|
|
268
363
|
flex-direction: column;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React binding for the plugin locale, which follows the DSH interface
|
|
3
|
+
* language (bridged from ctx.locale in client/index.ts). Surfaces that render
|
|
4
|
+
* tt() output subscribe to this tick so a DSH language switch re-renders them
|
|
5
|
+
* immediately.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useSyncExternalStore } from 'react'
|
|
9
|
+
import { getImageGenLanguageVersion, subscribeImageGenLanguage } from './helpers.ts'
|
|
10
|
+
|
|
11
|
+
/** Re-render the calling component whenever the DSH language changes. */
|
|
12
|
+
export function useImageGenLanguageTick(): number {
|
|
13
|
+
return useSyncExternalStore(subscribeImageGenLanguage, getImageGenLanguageVersion)
|
|
14
|
+
}
|