Skip to content

Commit

Permalink
Implement app-router architecture updated layouts (#123)
Browse files Browse the repository at this point in the history
* chore: initial app router work with navbar and menu

* refactor: move various caches to app router and delete custom express server

* chore: rename _api folder with better description

* chore: fetch data on initial server-side load

* refactor: split out shared image modal into separate page

* chore: initial work moving advanced options panel into app router

* chore: move panel to app router

* chore: move more components into app router

* chore: move pending and image pages over to app router

* chore: move settings page to app router

* chore: initial work to get image modal working with app router

* fix: image modal broke

* chore: fix css

* chore: move more components into app router

* chore: move InfoPage to app router

* feat: implement new landing page

* feat: create new landing page

* chore: remove chat option

* chore: remove a bunch of unneeded code

* chore: remove a whole bunch of code

* refactor: consolidate advanced options panel

* chore: css fixes

* chore: add additional images to landing page

* chore: move controlnet page over to app router

* feat: add dropdowns to various advanced options panels

* chore: update steps component to use new dropdown option

* feat: better filters for model selection

* feat: better filter for select model dropdown

* feat: debug page for outputting database

* chore: add new metadata pattern

* feat: implement dry-run calculation

* feat: toggle model favorites from options panel

* feat: add accordion component

* chore: fix types

* chore: fix and update lora selection

* chore: update livepaint and controlnet pages

* feat: implement new primary window controller

* fix: pending jobs disappear on page reload

* stash work

* feat: initial work on supporting multip clip and multi skip

* stash work

* feat: multi clip skip and multi-denoise

* feat: initial work on adding kudos calcs to jobs

* chore: fix issue with error pages

* initial build passes

* chore: update clsx

* chore: update packages

* fix build

* chore: initial work on keyword dropdown

* feat: Add loras

* fix: disable keyword button

* refactor: move model details and image orientation into dropdowns

* fix: keyword button disabled

* chore: remove unneeded code

* chore: add option to change pathname

* chore: add scaffolding for dimension management

* fix: spacing issues with buttons

* feat: attempt to add dynamic height to dropdown

* chore: work on toast popover

* chore: handle modal size

* fix: trying to fix linting errors and issue with dropdown sizes

* remove file

* ux work on settings page

* feat add concurrency option

* initial work on model info panel

* fix: order for checking if page is active

* stash work

* stash work

* stash work

* fix: typo in url

* fix: broken confirmation modal

* fix: build issues

* fix styles

* stash work

* pass model into modelsinfo

* feat: hide and fave models

* fix: tighten model info logic

* fix: hidden models

* fix: issue with samplers

* feat: create page settings dropdown

* feat: add slow workers to misc options

* fix: mobile styling issues with prompt input

* fix: fav models number does not update

* fix: more incorrect styles

* chore: update metadata fields

* refactor: update pending page layout

* fix: base path

* fix: shared links broken

* revert to older version of nexths

* fix: missing mobile footer

* feat: add support for custom color themes

* fix: refresh image gallery after delete

* restore GA

* fix: mobile navbar links

* fix: theme

* fix: more style fixes

* feat: new alert panel

* chore: update front page

* app update component

* fix: shuffled array

* more fixes

* fix host

* fix: UI on Mobile devices

* chore: fix GA

* chore: pending page improvements

* chore: remove file
  • Loading branch information
daveschumaker authored Aug 2, 2023
1 parent 5ffc42f commit 74b0899
Show file tree
Hide file tree
Showing 440 changed files with 13,687 additions and 12,883 deletions.
8 changes: 8 additions & 0 deletions BASE_PATH.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// const baseHost = 'http://staging.tinybots.net'
const baseHost = 'https://tinybots.net'
const basePath = '/artbot'

module.exports = {
baseHost,
basePath
}
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# 2023.08.01

- WELCOME TO THE NEWISH ARTBOT!
- Tons of changes! Where to even start.
- Updated web-app to use new app router architecture in NextJS.
- Compact and re-organize advanced options panel.
- Moved various toggles and sliders into relevant options menus that now appear next to relevant components (e.g., clicking the options panel on the Samplers dropdown will show an option to "use all samplers")
- New filter for model selection list. Easily filter by SFW / NSFW / favorites.
- Add model to favorites right from the model details panel on the create page.
- Add new options to create images using multiple denoise values and multiple CLIP values.
- Do you have frequently used custom dimensions? You can now save and reuse them.
- Tons more stuff!
- Thanks to Efreak, magic, and hmal on Discord for helping to beta test this!

# 2023.07.26

- Fix: Inverted image masks when using inpainting. Now, you should only need to highlight the areas you want to change. This used to work correctly, but an update to worker GPUs broke how ArtBot sent image masks to the AI Horde. You should be able to use inpainting as normal, now! Thanks to Silvy, Efreak and others for reporting this.
Expand Down
6 changes: 4 additions & 2 deletions _constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import AppSettings from 'models/AppSettings'
import { IOrientation } from '../types'

export const ANON_API_KEY = '0000000000'
Expand All @@ -6,11 +7,12 @@ export const HORDE_DEV = 'https://dev.aihorde.net'
export const RATING_API = 'https://ratings.aihorde.net'
export const CREATE_NEW_JOB_INTERVAL = 1500 // ms between new job requests
export const RATE_IMAGE_CUTOFF_SEC = 900
export const MAX_CONCURRENT_JOBS_ANON = 5
export const MAX_CONCURRENT_JOBS_USER = 10
export const MAX_CONCURRENT_JOBS_ANON = AppSettings.get('maxConcurrency') || 5
export const MAX_CONCURRENT_JOBS_USER = AppSettings.get('maxConcurrency') || 10
export const MAX_IMAGES_PER_JOB = 200
export const MAX_DIMENSIONS_LOGGED_IN = 2048
export const MAX_DIMENSIONS_LOGGED_OUT = 1024
export const MAX_STEPS_LOGGED_IN = 500
export const POLL_COMPLETED_JOBS_INTERVAL = 1500 // ms
export const DEFAULT_SAMPLER_ARRAY = [
'k_dpm_2_a',
Expand Down
10 changes: 9 additions & 1 deletion api/createImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface CreateImageResponse {
jobId?: string
status?: string
message?: string
kudos?: number
}

let isPending = false
Expand Down Expand Up @@ -53,9 +54,16 @@ export const createImage = async (

const statusCode = resp.status
const data = await resp.json()
const { id, message = '' }: GenerateResponse = data
const { id, message = '', kudos }: GenerateResponse = data
isPending = false

if (imageDetails.dry_run && kudos) {
return {
success: true,
kudos
}
}

if (message.indexOf('unethical images') >= 0) {
return {
success: false,
Expand Down
4 changes: 3 additions & 1 deletion api/createShortlink.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { basePath } from 'BASE_PATH'

export const createShortlink = async (obj: any = {}) => {
try {
const res = await fetch(`/artbot/api/create-shortlink`, {
const res = await fetch(`${basePath}/api/create-shortlink`, {
method: 'POST',
body: JSON.stringify(obj),
headers: {
Expand Down
7 changes: 4 additions & 3 deletions api/fetchAvailableModels.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { basePath } from 'BASE_PATH'
import StableDiffusionModel from '../models/StableDiffusionModel'
import { modelStore, setAvailableModels } from '../store/modelStore'
import { clientHeader, isAppActive } from '../utils/appUtils'
Expand Down Expand Up @@ -27,7 +28,7 @@ export const fetchAvailableModels = async () => {
try {
const res = await fetch(
isInitial
? `/artbot/api/models-available`
? `${basePath}/api/models-available`
: `https://aihorde.net/api/v2/status/models`,
{
headers: {
Expand All @@ -49,7 +50,7 @@ export const fetchAvailableModels = async () => {
console.log(`Warning: Unable to fetch available models. API offline?`)
} finally {
isPending = false
isInitial = false
// isInitial = false

return availableModels
}
Expand All @@ -75,7 +76,7 @@ export const buildModelAvailability = async () => {

if (validCount || currentModelCount === 0) {
// @ts-ignore
setAvailableModels(availableModelsMap)
setAvailableModels(modelAvailability)
}
}
}
3 changes: 2 additions & 1 deletion api/fetchHordePerformance.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { basePath } from 'BASE_PATH'
import { setHordePerformance } from '../store/appStore'

export const fetchHordePerformance = async () => {
try {
const res = await fetch(`/artbot/api/horde-performance`)
const res = await fetch(`${basePath}/api/horde-performance`)
const data = (await res.json()) || {}
const { perfStats } = data
if (perfStats) {
Expand Down
3 changes: 2 additions & 1 deletion api/fetchModelDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { IAvailableModels, IModelsDetails } from 'types/artbot'
import StableDiffusionModel from '../models/StableDiffusionModel'
import { setModelDetails } from '../store/modelStore'
import { isAppActive } from '../utils/appUtils'
import { basePath } from 'BASE_PATH'

let isPending = false
const fetchModelDetails = async () => {
Expand All @@ -18,7 +19,7 @@ const fetchModelDetails = async () => {
let availableModelsMap: IAvailableModels = {}

try {
const res = await fetch(`/artbot/api/model-details`)
const res = await fetch(`${basePath}/api/model-details`)
const { models }: { models: IModelsDetails } = await res.json()

for (const model in models) {
Expand Down
4 changes: 3 additions & 1 deletion api/fetchModelUpdates.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { basePath } from 'BASE_PATH'

let isPending = false

interface IModelUpdatesResponse {
Expand All @@ -21,7 +23,7 @@ export const fetchModelUpdates = async () => {
// let modelUpdates: Array<any> = []

try {
const res = await fetch(`/artbot/api/model-updates`)
const res = await fetch(`${basePath}/api/model-updates`)
const data: IModelUpdatesResponse = await res.json()
const { success, changes = [], timestamp } = data

Expand Down
3 changes: 2 additions & 1 deletion api/getFinishedImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const getFinishedImage = async (
const status = res.status
const data = await res.json()

const { generations, message, shared, faulted } = data
const { generations, kudos, message, shared, faulted } = data

if (status === 404) {
apiCooldown(5000)
Expand Down Expand Up @@ -156,6 +156,7 @@ export const getFinishedImage = async (
success: true,
jobId,
canRate: shared ? true : false,
kudos: kudos / generationDetails.length,
generations: generationDetails // Initial work to handle returning multiple images
}
}
Expand Down
3 changes: 2 additions & 1 deletion api/telemetry.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { basePath } from 'BASE_PATH'
import AppSettings from '../models/AppSettings'
import { logToConsole } from '../utils/debugTools'
import serverFetchWithTimeout from '../utils/serverFetchWithTimeout'
Expand Down Expand Up @@ -52,7 +53,7 @@ export const trackEvent = async (obj: any = {}) => {
// }

try {
serverFetchWithTimeout(`/artbot/api/telemetry`, {
serverFetchWithTimeout(`${basePath}/api/telemetry`, {
method: 'POST',
body: JSON.stringify(obj),
headers: {
Expand Down
53 changes: 0 additions & 53 deletions api/userInfo.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import AppSettings from '../models/AppSettings'
import { setHordeStatus } from '../store/appStore'
import {
IWorker,
setLoggedInState,
setUserInfo,
setWorkers,
userInfoStore
} from '../store/userStore'
import {
Expand Down Expand Up @@ -66,7 +64,6 @@ export const fetchUserDetails = async (apikey: string) => {
trusted = false,
username = '',
worker_ids = null,
sharedKey = false,
sharedkey_ids = []
} = userDetails

Expand Down Expand Up @@ -107,56 +104,6 @@ export const fetchUserDetails = async (apikey: string) => {
sharedkey_ids
})

if (worker_ids && worker_ids.length > 0) {
let workerInfo: { [key: string]: IWorker } = {}

for (const idx in worker_ids) {
const workerRes = await fetch(
`${getApiHostServer()}/api/v2/workers/${worker_ids[idx]}`,
{
headers: {
'Content-Type': 'application/json',
'Client-Agent': clientHeader()
}
}
)
const workerData = await workerRes.json()
const {
id,
kudos_rewards,
maintenance_mode,
max_pixels,
models,
name,
online,
performance,
requests_fulfilled,
team,
threads,
trusted,
uptime
} = workerData

workerInfo[id] = {
id,
kudos_rewards,
maintenance_mode,
max_pixels,
models,
name,
online,
performance,
requests_fulfilled,
team,
threads,
trusted,
uptime
}
}

setWorkers(workerInfo)
}

isPending = false
setHordeStatus(true)
return {
Expand Down
13 changes: 13 additions & 0 deletions app/(default-route-group)/about/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import AboutPage from 'app/_pages/AboutPage'
import { Metadata } from 'next'

export const metadata: Metadata = {
title: 'About - ArtBot for Stable Diffusion',
openGraph: {
title: 'ArtBot - About'
}
}

export default function Page() {
return <AboutPage />
}
13 changes: 13 additions & 0 deletions app/(default-route-group)/changelog/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import ChangelogPage from 'app/_pages/ChangelogPage'
import { Metadata } from 'next'

export const metadata: Metadata = {
title: 'Changelog - ArtBot for Stable Diffusion',
openGraph: {
title: 'ArtBot - Changelog'
}
}

export default function Page() {
return <ChangelogPage />
}
26 changes: 26 additions & 0 deletions app/(default-route-group)/contact/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { baseHost, basePath } from 'BASE_PATH'
import ContactPage from 'app/_pages/ContactPage'
import { Metadata } from 'next'

export const metadata: Metadata = {
title: 'Contact Us - ArtBot for Stable Diffusion',
openGraph: {
type: 'website',
url: `${baseHost}${basePath}`,
title: 'ArtBot - Contact Form',
images: [
{
url: '/artbot/robots_communicating.jpg'
}
]
},
twitter: {
card: 'summary_large_image',
creator: '@davely',
images: `${baseHost}${basePath}/robots_communicating.jpg`
}
}

export default function Page() {
return <ContactPage />
}
28 changes: 28 additions & 0 deletions app/(default-route-group)/controlnet/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { baseHost, basePath } from 'BASE_PATH'
import ControlNet from 'app/_pages/ControlNetPage'
import { Metadata } from 'next'

export const metadata: Metadata = {
title: 'ControlNet - ArtBot for Stable Diffusion',
openGraph: {
type: 'website',
url: `${baseHost}${basePath}`,
title: 'ArtBot - ControlNet',
description:
'Use a source image and text prompt to better control diffusion models, and create amazing images with generative AI powered by Stable Diffusion.',
images: [
{
url: `${baseHost}${basePath}/robot_control.jpg`
}
]
},
twitter: {
card: 'summary_large_image',
creator: '@davely',
images: `${baseHost}${basePath}/robot_control.jpg`
}
}

export default function Page() {
return <ControlNet />
}
36 changes: 36 additions & 0 deletions app/(default-route-group)/create/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { basePath } from 'BASE_PATH'
import CreatePage from 'app/_pages/CreatePage'

async function getPageData() {
let availableModels: Array<any> = []
let modelDetails: any = {}

try {
const availableModelsRes = await fetch(
`http://localhost:${process.env.PORT}${basePath}/api/models-available`
)
const availableModelsData = (await availableModelsRes.json()) || {}
availableModels = availableModelsData.models

const modelDetailsRes = await fetch(
`http://localhost:${process.env.PORT}${basePath}/api/model-details`
)
const modelDetailsData = (await modelDetailsRes.json()) || {}
modelDetails = modelDetailsData.models
} catch (err) {}

return {
availableModels,
modelDetails
}
}

export default async function Page() {
// Fetch data directly in a Server Component
const { availableModels, modelDetails } = await getPageData()

// Forward fetched data to your Client Component
return (
<CreatePage availableModels={availableModels} modelDetails={modelDetails} />
)
}
5 changes: 5 additions & 0 deletions app/(default-route-group)/debug-export/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import LastResort from 'app/_pages/SettingsPage/LastResort'

export default function Page() {
return <LastResort />
}
5 changes: 5 additions & 0 deletions app/(default-route-group)/draw/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import DrawPage from 'app/_pages/DrawPage'

export default function Page() {
return <DrawPage />
}
Loading

0 comments on commit 74b0899

Please sign in to comment.