From eb15a6f2de506b460d3a458e6ee50ac2edbd7a62 Mon Sep 17 00:00:00 2001 From: Dave Schumaker Date: Fri, 6 Sep 2024 13:51:40 -0700 Subject: [PATCH] fix: update default TurboMix LoRA (#51) * fix: update default TurboMix LoRA * feat: add build id to footer * chore: update footer padding and add animated "Made With" emoji component * chore: update changelog --- .../stylePresetSelectComponent.tsx | 6 ++-- app/_components/Footer/AnimatedEmoji.tsx | 17 ++++++++++ app/_components/Footer/buildId.tsx | 10 ++++++ app/_components/Footer/footer.module.css | 4 +-- app/_components/Footer/index.tsx | 12 ++++--- app/_data-models/PromptInput.test.ts | 6 ++-- app/_data-models/PromptInput.ts | 32 +++++++++++++------ app/_hooks/usePromptInputValidation.tsx | 23 +++++++++++++ app/changelog/_updates/2024.09.06.md | 6 ++++ app/layout.tsx | 1 - 10 files changed, 95 insertions(+), 22 deletions(-) create mode 100644 app/_components/Footer/AnimatedEmoji.tsx create mode 100644 app/_components/Footer/buildId.tsx create mode 100644 app/changelog/_updates/2024.09.06.md diff --git a/app/_components/AdvancedOptions/StylePresetSelect/stylePresetSelectComponent.tsx b/app/_components/AdvancedOptions/StylePresetSelect/stylePresetSelectComponent.tsx index b9895c7..5787f22 100644 --- a/app/_components/AdvancedOptions/StylePresetSelect/stylePresetSelectComponent.tsx +++ b/app/_components/AdvancedOptions/StylePresetSelect/stylePresetSelectComponent.tsx @@ -14,7 +14,7 @@ import { StylePreviewConfigurations } from '@/app/_types/HordeTypes' import { useCallback } from 'react' -import PromptInput, { DEFAULT_TURBO_LORA } from '@/app/_data-models/PromptInput' +import PromptInput, { DEFAULT_TURBO_EULER_LORA } from '@/app/_data-models/PromptInput' import { SavedLora } from '@/app/_data-models/Civitai' import { useStore } from 'statery' import { ModelStore } from '@/app/_stores/ModelStore' @@ -57,8 +57,8 @@ export default function StylePresetSelectComponent({ updateInput.loras = [] presetSettings.loras.forEach((lora) => { let updateLora: SavedLora - if (lora.name == '247778') { - updateLora = DEFAULT_TURBO_LORA + if (lora.name == DEFAULT_TURBO_EULER_LORA.versionId) { + updateLora = DEFAULT_TURBO_EULER_LORA } else { updateLora = new SavedLora({ id: lora.name, diff --git a/app/_components/Footer/AnimatedEmoji.tsx b/app/_components/Footer/AnimatedEmoji.tsx new file mode 100644 index 0000000..7fcf001 --- /dev/null +++ b/app/_components/Footer/AnimatedEmoji.tsx @@ -0,0 +1,17 @@ +import React, { useState, useEffect } from 'react'; + +const emojis = ['🎨', '😀', '🖌️', '🖍️', '☀️', '🍻', '❤️', '🎉', '🦄', '🤖', '💻', '😬', '🤪', '✨']; + +export default function AnimatedEmoji() { + const [currentEmoji, setCurrentEmoji] = useState(emojis[0]); + + useEffect(() => { + const interval = setInterval(() => { + setCurrentEmoji(emojis[Math.floor(Math.random() * emojis.length)]); + }, 3000); + + return () => clearInterval(interval); + }, []); + + return {currentEmoji}; +} \ No newline at end of file diff --git a/app/_components/Footer/buildId.tsx b/app/_components/Footer/buildId.tsx new file mode 100644 index 0000000..2dd391a --- /dev/null +++ b/app/_components/Footer/buildId.tsx @@ -0,0 +1,10 @@ +import { AppStore } from "@/app/_stores/AppStore" +import { useStore } from "statery" + +export default function BuildId() { + const { buildId } = useStore(AppStore) + + if (!buildId) return null + + return
v{buildId}
+} \ No newline at end of file diff --git a/app/_components/Footer/footer.module.css b/app/_components/Footer/footer.module.css index d5289bb..978a1de 100644 --- a/app/_components/Footer/footer.module.css +++ b/app/_components/Footer/footer.module.css @@ -5,7 +5,7 @@ flex-direction: column; margin-top: 16px; padding: 16px 32px; - padding-bottom: 66px; + padding-bottom: 72px; width: 100%; } @@ -38,7 +38,7 @@ .AboutWrapper { margin-top: 32px; - padding-bottom: 16px; + /* padding-bottom: 16px; */ text-align: center; } diff --git a/app/_components/Footer/index.tsx b/app/_components/Footer/index.tsx index 6d0ec1a..8c45ab7 100644 --- a/app/_components/Footer/index.tsx +++ b/app/_components/Footer/index.tsx @@ -8,11 +8,14 @@ import { IconCamera, IconExternalLink, IconInfoCircle, + IconMessage, IconPhoto, IconQuestionMark, IconRobot } from '@tabler/icons-react' import Linker from '../Linker' +import BuildId from './buildId' +import AnimatedEmoji from './AnimatedEmoji' export default function Footer() { const pathname = usePathname() @@ -164,10 +167,10 @@ export default function Footer() {
- {/*
+
Contact -
*/} +
- ArtBot is created with ❤️ , ☕️ and ☀️ by{' '} + ArtBot is created with by{' '} @@ -275,6 +278,7 @@ export default function Footer() { in California.
+
) } diff --git a/app/_data-models/PromptInput.test.ts b/app/_data-models/PromptInput.test.ts index ed80d11..95a9d15 100644 --- a/app/_data-models/PromptInput.test.ts +++ b/app/_data-models/PromptInput.test.ts @@ -1,4 +1,4 @@ -import PromptInput, { DEFAULT_TURBO_LORA } from './PromptInput' +import PromptInput, { DEFAULT_TURBO_EULER_LORA } from './PromptInput' import { JobType } from '@/app/_types/ArtbotTypes' import { SourceProcessing } from '@/app/_types/HordeTypes' import { SavedLora } from './Civitai' @@ -93,7 +93,7 @@ describe('PromptInput', () => { it('should correctly set non-turbo default prompt input', () => { const input = new PromptInput({ - loras: [DEFAULT_TURBO_LORA, { id: 'other', versionId: 'other' } as SavedLora] + loras: [DEFAULT_TURBO_EULER_LORA, { id: 'other', versionId: 'other' } as SavedLora] }) const result = PromptInput.setNonTurboDefaultPromptInput(input) @@ -112,6 +112,6 @@ describe('PromptInput', () => { expect(result.steps).toBe(8) expect(result.cfg_scale).toBe(2) expect(result.loras).toHaveLength(2) - expect(result.loras[0]).toEqual(DEFAULT_TURBO_LORA) + expect(result.loras[0]).toEqual(DEFAULT_TURBO_EULER_LORA) }) }) diff --git a/app/_data-models/PromptInput.ts b/app/_data-models/PromptInput.ts index 54f2ed5..e30c97b 100644 --- a/app/_data-models/PromptInput.ts +++ b/app/_data-models/PromptInput.ts @@ -7,7 +7,7 @@ import { } from '@/app/_types/HordeTypes' import { SavedEmbedding, SavedLora } from './Civitai' -export const DEFAULT_TURBO_LORA = new SavedLora({ +export const DEFAULT_TURBO_SDE_LORA = new SavedLora({ id: '247778', civitAiType: 'LORA', versionId: '247778', @@ -18,6 +18,17 @@ export const DEFAULT_TURBO_LORA = new SavedLora({ clip: 1 }) +export const DEFAULT_TURBO_EULER_LORA = new SavedLora({ + id: '246747', + civitAiType: 'LORA', + versionId: '246747', + versionName: '', + isArtbotManualEntry: true, + name: 'SDXL | TurboMix LoRA (Euler sampler)', + strength: 1, + clip: 1 +}) + class PromptInput { // ArtBot ID for mainting relationships in IndexedDb artbot_id: string = '' @@ -56,7 +67,7 @@ class PromptInput { jobType: JobType = JobType.Text2Img karras: boolean = true loras: SavedLora[] = [ - DEFAULT_TURBO_LORA + DEFAULT_TURBO_EULER_LORA ] models: Array = ['AlbedoBase XL (SDXL)'] negative: string = '' @@ -88,9 +99,10 @@ class PromptInput { * @returns True if the prompt input is a default prompt, false otherwise. */ static isDefaultPromptInput(input: PromptInput): boolean { - const hasTurboLora = input.loras.filter(lora => lora.versionId === '247778').length > 0 + const hasTurboLora = input.loras.filter(lora => lora.versionId === DEFAULT_TURBO_EULER_LORA.versionId).length > 0 + const hasDefaultSampler = input.sampler === 'k_euler_a' const hasDefaultStepsAndCfgScale = input.models[0] === 'AlbedoBase XL (SDXL)' && Number(input.steps) === 8 && Number(input.cfg_scale) === 2 - const hasDefaultModelAndLora = input.models[0] === 'AlbedoBase XL (SDXL)' && hasTurboLora + const hasDefaultModelAndLora = input.models[0] === 'AlbedoBase XL (SDXL)' && hasTurboLora && hasDefaultSampler return hasDefaultStepsAndCfgScale || hasDefaultModelAndLora } @@ -104,7 +116,7 @@ class PromptInput { */ static setNonTurboDefaultPromptInput(input: PromptInput): PromptInput { // Remove the LCM TurboMix LoRA if present - input.loras = input.loras.filter(lora => lora.versionId != '247778'); + input.loras = input.loras.filter(lora => lora.versionId != DEFAULT_TURBO_EULER_LORA.versionId); return new PromptInput({ ...input, @@ -116,18 +128,20 @@ class PromptInput { /** * Sets the prompt input to a turbo default prompt. This occurs when a user * selects a SDXL turbo model, so we need to adjust steps, cfg_scale, and - * add the LCM TurboMix LoRA to the loras array. + * add the TurboMix LoRA to the loras array. * @param input - The prompt input to set to a turbo default prompt. * @returns The prompt input set to a turbo default prompt. */ static setTurboDefaultPromptInput(input: PromptInput): PromptInput { - // Check if the LCM TurboMix LoRA is not present in the input.loras array - if (!input.loras.some(lora => lora.versionId == '247778')) { + // Check if the TurboMix LoRA is not present in the input.loras array + if (!input.loras.some(lora => lora.versionId == DEFAULT_TURBO_EULER_LORA.versionId)) { // If not present, add it to the beginning of the array - input.loras.unshift(DEFAULT_TURBO_LORA); + input.loras.unshift(DEFAULT_TURBO_EULER_LORA); } + + return new PromptInput({ ...input, steps: 8, diff --git a/app/_hooks/usePromptInputValidation.tsx b/app/_hooks/usePromptInputValidation.tsx index f6723e3..5eabf16 100644 --- a/app/_hooks/usePromptInputValidation.tsx +++ b/app/_hooks/usePromptInputValidation.tsx @@ -7,6 +7,7 @@ import { useStore } from 'statery' import { ModelStore } from '../_stores/ModelStore' import { Workflow } from '../_types/ArtbotTypes' import { AppConstants } from '../_data-models/AppConstants' +import { DEFAULT_TURBO_EULER_LORA, DEFAULT_TURBO_SDE_LORA } from '../_data-models/PromptInput' export interface PromptError { message: string @@ -98,6 +99,28 @@ export default function usePromptInputValidation(): [PromptError[], boolean] { } }) + // Check if using TurboMix LoRA with correct sampler + if ( + input.loras.filter(lora => lora.versionId === DEFAULT_TURBO_EULER_LORA.versionId).length > 0 && + input.sampler !== 'k_euler_a' + ) { + updateErrors.push({ + message: 'TurboMix Euler LoRA requires "k_euler_a" sampler', + type: 'warning' + }) + } + + // Check if using TurboMix LoRA with correct sampler + if ( + input.loras.filter(lora => lora.versionId === DEFAULT_TURBO_SDE_LORA.versionId).length > 0 && + input.sampler !== 'k_dpmpp_sde' + ) { + updateErrors.push({ + message: 'TurboMix LCM SDE LoRA requires "k_dpmpp_sde" sampler', + type: 'warning' + }) + } + // Remix is only availble with Stable Cascade 1.0 if ( input.models[0] !== 'Stable Cascade 1.0' && diff --git a/app/changelog/_updates/2024.09.06.md b/app/changelog/_updates/2024.09.06.md new file mode 100644 index 0000000..cc4395a --- /dev/null +++ b/app/changelog/_updates/2024.09.06.md @@ -0,0 +1,6 @@ +# 2024.08.29 (v2.0.6-beta) + +- (fix) Update default TurboMix LoRA due to change in default sampler (k_euler_a) +- (fix) Padding issues with footer +- (feat) Add build ID to footer +- (feat) Update "Made with" message in footer to use random rotating emoji diff --git a/app/layout.tsx b/app/layout.tsx index 6793e58..1f932e4 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -74,7 +74,6 @@ export default function RootLayout({ className="flex flex-col flex-1" style={{ padding: '42px 0 0 0', - paddingBottom: 'var(--footer-padding)' }} >