diff --git a/src/app/components/prompt-style-modal/prompt-style-modal.component.html b/src/app/components/prompt-style-modal/prompt-style-modal.component.html index de8844c..f6ccab0 100644 --- a/src/app/components/prompt-style-modal/prompt-style-modal.component.html +++ b/src/app/components/prompt-style-modal/prompt-style-modal.component.html @@ -12,7 +12,7 @@

{{ 'app.prompt_style.choose' | transloco }}

@for (style of stylesByCategory()[category]; track style.name) {
-
+
{{ style.name }}
{{ 'app.generate.model' | transloco }}: {{ style.model }}
@@ -26,6 +26,18 @@

{{ 'app.prompt_style.choose' | transloco }}


+ @if (style.loras?.length) { + {{'app.generate.lora_list' | transloco}}: + @if (loraNames()[style.name]?.length) { +
    + @for (lora of loraNames()[style.name]!; track lora) { +
  • {{lora}}
  • + } +
+ } +
+ } +
diff --git a/src/app/components/prompt-style-modal/prompt-style-modal.component.ts b/src/app/components/prompt-style-modal/prompt-style-modal.component.ts index 5ccf7eb..6e9bc65 100644 --- a/src/app/components/prompt-style-modal/prompt-style-modal.component.ts +++ b/src/app/components/prompt-style-modal/prompt-style-modal.component.ts @@ -7,6 +7,12 @@ import {TranslocoPipe} from "@ngneat/transloco"; import {BoxComponent} from "../box/box.component"; import {PromptStyleTextComponent} from "../prompt-style-text/prompt-style-text.component"; import {ModalService} from "../../services/modal.service"; +import {LoraNamePipe} from "../../pipes/lora-name.pipe"; +import {AsyncPipe} from "@angular/common"; +import {CivitAiService} from "../../services/civit-ai.service"; +import {catchError, map, Observable, of, tap} from "rxjs"; +import {CivitAiModel} from "../../types/civit-ai/civit-ai-model"; +import {TranslatorService} from "../../services/translator.service"; @Component({ selector: 'app-prompt-style-modal', @@ -15,12 +21,16 @@ import {ModalService} from "../../services/modal.service"; LoaderComponent, TranslocoPipe, BoxComponent, - PromptStyleTextComponent + PromptStyleTextComponent, + LoraNamePipe, + AsyncPipe ], templateUrl: './prompt-style-modal.component.html', styleUrl: './prompt-style-modal.component.scss' }) export class PromptStyleModalComponent implements OnInit { + private loraNameCache: Record = {}; + public originalPrompt = input.required(); public originalNegativePrompt = input.required(); @@ -41,11 +51,15 @@ export class PromptStyleModalComponent implements OnInit { public collapsed = signal<{[style:string]: boolean | undefined}>({}); public loading = signal(true); + public loraNames = signal>({}); + public styleChosen = output(); constructor( private readonly repoData: HordeRepoDataService, private readonly modalService: ModalService, + private readonly civitAi: CivitAiService, + private readonly translator: TranslatorService, ) { } @@ -65,4 +79,36 @@ export class PromptStyleModalComponent implements OnInit { this.styleChosen.emit(style); await this.modalService.close(); } + + public async loadLoraNames(style: EnrichedPromptStyle) { + const promises: Promise[] = []; + for (const lora of (style.loras ?? [])) { + let observable: Observable; + const cacheKey = lora.name + String(lora.is_version ?? false); + if (this.loraNameCache[cacheKey]) { + observable = of(this.loraNameCache[cacheKey]); + } else { + if (lora.is_version) { + observable = this.civitAi.getLoraByVersion(Number(lora.name)); + } else { + observable = this.civitAi.getLoraDetail(Number(lora.name)); + } + observable = observable.pipe( + tap (lora => this.loraNameCache[cacheKey] = lora), + ); + } + + promises.push(toPromise(observable.pipe( + map (lora => lora.name), + catchError(() => this.translator.get('app.lora.unknown')), + ))); + } + + const result = await Promise.all(promises); + this.loraNames.update(loraNames => { + loraNames[style.name] = result; + + return {...loraNames}; + }); + } } diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index d074c24..dc264af 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -210,5 +210,6 @@ "app.worker.pause": "Pause worker", "app.worker.resume": "Resume worker", "app.lora.broken": "The CivitAI api is currently broken and you can only see the latest version of a LoRa. This needs to be fixed on CivitAI's side and there's nothing we can do.", - "app.generate.style_name": "Style name" + "app.generate.style_name": "Style name", + "app.lora.unknown": "Unknown LoRA (failed to fetch from CivitAI)" }