wip
This commit is contained in:
2
web_app/src/lib/const.ts
Normal file
2
web_app/src/lib/const.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export const ACCENT_COLOR = "#ffcc00bb"
|
||||
export const DEFAULT_BRUSH_SIZE = 40
|
||||
118
web_app/src/lib/states.ts
Normal file
118
web_app/src/lib/states.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import { create, StoreApi, UseBoundStore } from "zustand"
|
||||
import { persist } from "zustand/middleware"
|
||||
import { immer } from "zustand/middleware/immer"
|
||||
import { SortBy, SortOrder } from "./types"
|
||||
import { DEFAULT_BRUSH_SIZE } from "./const"
|
||||
|
||||
type FileManagerState = {
|
||||
sortBy: SortBy
|
||||
sortOrder: SortOrder
|
||||
layout: "rows" | "masonry"
|
||||
searchText: string
|
||||
}
|
||||
|
||||
type AppState = {
|
||||
file: File | null
|
||||
imageHeight: number
|
||||
imageWidth: number
|
||||
brushSize: number
|
||||
brushSizeScale: number
|
||||
|
||||
isInpainting: boolean
|
||||
isInteractiveSeg: boolean // 是否正处于 sam 状态
|
||||
isInteractiveSegRunning: boolean
|
||||
interactiveSegClicks: number[][]
|
||||
|
||||
prompt: string
|
||||
|
||||
fileManagerState: FileManagerState
|
||||
}
|
||||
|
||||
type AppAction = {
|
||||
setFile: (file: File) => void
|
||||
setIsInpainting: (newValue: boolean) => void
|
||||
setBrushSize: (newValue: number) => void
|
||||
setImageSize: (width: number, height: number) => void
|
||||
setFileManagerSortBy: (newValue: SortBy) => void
|
||||
setFileManagerSortOrder: (newValue: SortOrder) => void
|
||||
setFileManagerLayout: (
|
||||
newValue: AppState["fileManagerState"]["layout"]
|
||||
) => void
|
||||
setFileManagerSearchText: (newValue: string) => void
|
||||
setPrompt: (newValue: string) => void
|
||||
}
|
||||
|
||||
export const useStore = create<AppState & AppAction>()(
|
||||
immer(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
file: null,
|
||||
imageHeight: 0,
|
||||
imageWidth: 0,
|
||||
brushSize: DEFAULT_BRUSH_SIZE,
|
||||
brushSizeScale: 1,
|
||||
isInpainting: false,
|
||||
isInteractiveSeg: false,
|
||||
isInteractiveSegRunning: false,
|
||||
interactiveSegClicks: [],
|
||||
prompt: "",
|
||||
fileManagerState: {
|
||||
sortBy: SortBy.CTIME,
|
||||
sortOrder: SortOrder.DESCENDING,
|
||||
layout: "masonry",
|
||||
searchText: "",
|
||||
},
|
||||
setIsInpainting: (newValue: boolean) =>
|
||||
set((state: AppState) => {
|
||||
state.isInpainting = newValue
|
||||
}),
|
||||
setFile: (file: File) =>
|
||||
set((state: AppState) => {
|
||||
// TODO: 清空各种状态
|
||||
state.file = file
|
||||
}),
|
||||
setBrushSize: (newValue: number) =>
|
||||
set((state: AppState) => {
|
||||
state.brushSize = newValue
|
||||
}),
|
||||
setImageSize: (width: number, height: number) => {
|
||||
// 根据图片尺寸调整 brushSize 的 scale
|
||||
set((state: AppState) => {
|
||||
state.imageWidth = width
|
||||
state.imageHeight = height
|
||||
state.brushSizeScale = Math.max(Math.min(width, height), 512) / 512
|
||||
})
|
||||
},
|
||||
setPrompt: (newValue: string) =>
|
||||
set((state: AppState) => {
|
||||
state.prompt = newValue
|
||||
}),
|
||||
setFileManagerSortBy: (newValue: SortBy) =>
|
||||
set((state: AppState) => {
|
||||
state.fileManagerState.sortBy = newValue
|
||||
}),
|
||||
setFileManagerSortOrder: (newValue: SortOrder) =>
|
||||
set((state: AppState) => {
|
||||
state.fileManagerState.sortOrder = newValue
|
||||
}),
|
||||
setFileManagerLayout: (newValue: "rows" | "masonry") =>
|
||||
set((state: AppState) => {
|
||||
state.fileManagerState.layout = newValue
|
||||
}),
|
||||
setFileManagerSearchText: (newValue: string) =>
|
||||
set((state: AppState) => {
|
||||
state.fileManagerState.searchText = newValue
|
||||
}),
|
||||
}),
|
||||
{
|
||||
name: "ZUSTAND_STATE", // name of the item in the storage (must be unique)
|
||||
partialize: (state) =>
|
||||
Object.fromEntries(
|
||||
Object.entries(state).filter(([key]) =>
|
||||
["fileManagerState", "prompt"].includes(key)
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1,23 +1,6 @@
|
||||
import { atom, selector } from "recoil"
|
||||
import _ from "lodash"
|
||||
|
||||
export enum HDStrategy {
|
||||
ORIGINAL = "Original",
|
||||
RESIZE = "Resize",
|
||||
CROP = "Crop",
|
||||
}
|
||||
|
||||
export enum LDMSampler {
|
||||
ddim = "ddim",
|
||||
plms = "plms",
|
||||
}
|
||||
|
||||
function strEnum<T extends string>(o: Array<T>): { [K in T]: K } {
|
||||
return o.reduce((res, key) => {
|
||||
res[key] = key
|
||||
return res
|
||||
}, Object.create(null))
|
||||
}
|
||||
import { CV2Flag, HDStrategy, LDMSampler, ModelsHDSettings } from "./types"
|
||||
|
||||
export enum AIModel {
|
||||
LAMA = "lama",
|
||||
@@ -75,18 +58,12 @@ export interface Rect {
|
||||
}
|
||||
|
||||
interface AppState {
|
||||
file: File | undefined
|
||||
imageHeight: number
|
||||
imageWidth: number
|
||||
disableShortCuts: boolean
|
||||
isInpainting: boolean
|
||||
isDisableModelSwitch: boolean
|
||||
isEnableAutoSaving: boolean
|
||||
isInteractiveSeg: boolean
|
||||
isInteractiveSegRunning: boolean
|
||||
interactiveSegClicks: number[][]
|
||||
enableFileManager: boolean
|
||||
brushSize: number
|
||||
isControlNet: boolean
|
||||
controlNetMethod: string
|
||||
plugins: string[]
|
||||
@@ -96,18 +73,12 @@ interface AppState {
|
||||
export const appState = atom<AppState>({
|
||||
key: "appState",
|
||||
default: {
|
||||
file: undefined,
|
||||
imageHeight: 0,
|
||||
imageWidth: 0,
|
||||
disableShortCuts: false,
|
||||
isInpainting: false,
|
||||
isDisableModelSwitch: false,
|
||||
isEnableAutoSaving: false,
|
||||
isInteractiveSeg: false,
|
||||
isInteractiveSegRunning: false,
|
||||
interactiveSegClicks: [],
|
||||
enableFileManager: false,
|
||||
brushSize: 40,
|
||||
isControlNet: false,
|
||||
controlNetMethod: ControlNetMethod.canny,
|
||||
plugins: [],
|
||||
@@ -115,28 +86,11 @@ export const appState = atom<AppState>({
|
||||
},
|
||||
})
|
||||
|
||||
export const propmtState = atom<string>({
|
||||
key: "promptState",
|
||||
default: "",
|
||||
})
|
||||
|
||||
export const negativePropmtState = atom<string>({
|
||||
key: "negativePromptState",
|
||||
default: "",
|
||||
})
|
||||
|
||||
export const isInpaintingState = selector({
|
||||
key: "isInpainting",
|
||||
get: ({ get }) => {
|
||||
const app = get(appState)
|
||||
return app.isInpainting
|
||||
},
|
||||
set: ({ get, set }, newValue: any) => {
|
||||
const app = get(appState)
|
||||
set(appState, { ...app, isInpainting: newValue })
|
||||
},
|
||||
})
|
||||
|
||||
export const isPluginRunningState = selector({
|
||||
key: "isPluginRunningState",
|
||||
get: ({ get }) => {
|
||||
@@ -175,42 +129,6 @@ export const serverConfigState = selector({
|
||||
},
|
||||
})
|
||||
|
||||
export const brushSizeState = selector({
|
||||
key: "brushSizeState",
|
||||
get: ({ get }) => {
|
||||
const app = get(appState)
|
||||
return app.brushSize
|
||||
},
|
||||
set: ({ get, set }, newValue: any) => {
|
||||
const app = get(appState)
|
||||
set(appState, { ...app, brushSize: newValue })
|
||||
},
|
||||
})
|
||||
|
||||
export const imageHeightState = selector({
|
||||
key: "imageHeightState",
|
||||
get: ({ get }) => {
|
||||
const app = get(appState)
|
||||
return app.imageHeight
|
||||
},
|
||||
set: ({ get, set }, newValue: any) => {
|
||||
const app = get(appState)
|
||||
set(appState, { ...app, imageHeight: newValue })
|
||||
},
|
||||
})
|
||||
|
||||
export const imageWidthState = selector({
|
||||
key: "imageWidthState",
|
||||
get: ({ get }) => {
|
||||
const app = get(appState)
|
||||
return app.imageWidth
|
||||
},
|
||||
set: ({ get, set }, newValue: any) => {
|
||||
const app = get(appState)
|
||||
set(appState, { ...app, imageWidth: newValue })
|
||||
},
|
||||
})
|
||||
|
||||
export const enableFileManagerState = selector({
|
||||
key: "enableFileManagerState",
|
||||
get: ({ get }) => {
|
||||
@@ -223,30 +141,6 @@ export const enableFileManagerState = selector({
|
||||
},
|
||||
})
|
||||
|
||||
export const fileState = selector({
|
||||
key: "fileState",
|
||||
get: ({ get }) => {
|
||||
const app = get(appState)
|
||||
return app.file
|
||||
},
|
||||
set: ({ get, set }, newValue: any) => {
|
||||
const app = get(appState)
|
||||
set(appState, {
|
||||
...app,
|
||||
file: newValue,
|
||||
interactiveSegClicks: [],
|
||||
isInteractiveSeg: false,
|
||||
isInteractiveSegRunning: false,
|
||||
})
|
||||
|
||||
const setting = get(settingState)
|
||||
set(settingState, {
|
||||
...setting,
|
||||
sdScale: 100,
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
export const isInteractiveSegState = selector({
|
||||
key: "isInteractiveSegState",
|
||||
get: ({ get }) => {
|
||||
@@ -275,9 +169,7 @@ export const isProcessingState = selector({
|
||||
key: "isProcessingState",
|
||||
get: ({ get }) => {
|
||||
const app = get(appState)
|
||||
return (
|
||||
app.isInteractiveSegRunning || app.isPluginRunning || app.isInpainting
|
||||
)
|
||||
return app.isInteractiveSegRunning || app.isPluginRunning
|
||||
},
|
||||
})
|
||||
|
||||
@@ -339,20 +231,6 @@ export const croperState = atom<Rect>({
|
||||
},
|
||||
})
|
||||
|
||||
export const SIDE_PANEL_TAB = strEnum(["inpainting", "outpainting"])
|
||||
export type SIDE_PANEL_TAB_TYPE = keyof typeof SIDE_PANEL_TAB
|
||||
|
||||
export interface SidePanelState {
|
||||
tab: SIDE_PANEL_TAB_TYPE
|
||||
}
|
||||
|
||||
export const sidePanelTabState = atom<SidePanelState>({
|
||||
key: "sidePanelTabState",
|
||||
default: {
|
||||
tab: SIDE_PANEL_TAB.inpainting,
|
||||
},
|
||||
})
|
||||
|
||||
export const croperX = selector({
|
||||
key: "croperX",
|
||||
get: ({ get }) => get(croperState).x,
|
||||
@@ -435,43 +313,6 @@ export const extenderWidth = selector({
|
||||
},
|
||||
})
|
||||
|
||||
interface ToastAtomState {
|
||||
open: boolean
|
||||
desc: string
|
||||
state: ToastState
|
||||
duration: number
|
||||
}
|
||||
|
||||
export const toastState = atom<ToastAtomState>({
|
||||
key: "toastState",
|
||||
default: {
|
||||
open: false,
|
||||
desc: "",
|
||||
state: "default",
|
||||
duration: 3000,
|
||||
},
|
||||
})
|
||||
|
||||
export const shortcutsState = atom<boolean>({
|
||||
key: "shortcutsState",
|
||||
default: false,
|
||||
})
|
||||
|
||||
export interface HDSettings {
|
||||
hdStrategy: HDStrategy
|
||||
hdStrategyResizeLimit: number
|
||||
hdStrategyCropTrigerSize: number
|
||||
hdStrategyCropMargin: number
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
type ModelsHDSettings = { [key in AIModel]: HDSettings }
|
||||
|
||||
export enum CV2Flag {
|
||||
INPAINT_NS = "INPAINT_NS",
|
||||
INPAINT_TELEA = "INPAINT_TELEA",
|
||||
}
|
||||
|
||||
export interface Settings {
|
||||
show: boolean
|
||||
showCroper: boolean
|
||||
@@ -490,7 +331,6 @@ export interface Settings {
|
||||
|
||||
// For SD
|
||||
sdMaskBlur: number
|
||||
sdMode: SDMode
|
||||
sdStrength: number
|
||||
sdSteps: number
|
||||
sdGuidanceScale: number
|
||||
@@ -656,7 +496,6 @@ export const settingStateDefault: Settings = {
|
||||
|
||||
// SD
|
||||
sdMaskBlur: 5,
|
||||
sdMode: SDMode.inpainting,
|
||||
sdStrength: 0.75,
|
||||
sdSteps: 50,
|
||||
sdGuidanceScale: 7.5,
|
||||
@@ -819,70 +658,3 @@ export const isDiffusionModelsState = selector({
|
||||
return isSD || isPaintByExample || isPix2Pix
|
||||
},
|
||||
})
|
||||
|
||||
export enum SortBy {
|
||||
NAME = "name",
|
||||
CTIME = "ctime",
|
||||
MTIME = "mtime",
|
||||
}
|
||||
|
||||
export enum SortOrder {
|
||||
DESCENDING = "desc",
|
||||
ASCENDING = "asc",
|
||||
}
|
||||
|
||||
interface FileManagerState {
|
||||
sortBy: SortBy
|
||||
sortOrder: SortOrder
|
||||
layout: "rows" | "masonry"
|
||||
searchText: string
|
||||
}
|
||||
|
||||
const FILE_MANAGER_STATE_KEY = "fileManagerState"
|
||||
|
||||
export const fileManagerState = atom<FileManagerState>({
|
||||
key: FILE_MANAGER_STATE_KEY,
|
||||
default: {
|
||||
sortBy: SortBy.CTIME,
|
||||
sortOrder: SortOrder.DESCENDING,
|
||||
layout: "masonry",
|
||||
searchText: "",
|
||||
},
|
||||
effects: [localStorageEffect(FILE_MANAGER_STATE_KEY)],
|
||||
})
|
||||
|
||||
export const fileManagerSortBy = selector({
|
||||
key: "fileManagerSortBy",
|
||||
get: ({ get }) => get(fileManagerState).sortBy,
|
||||
set: ({ get, set }, newValue: any) => {
|
||||
const val = get(fileManagerState)
|
||||
set(fileManagerState, { ...val, sortBy: newValue })
|
||||
},
|
||||
})
|
||||
|
||||
export const fileManagerSortOrder = selector({
|
||||
key: "fileManagerSortOrder",
|
||||
get: ({ get }) => get(fileManagerState).sortOrder,
|
||||
set: ({ get, set }, newValue: any) => {
|
||||
const val = get(fileManagerState)
|
||||
set(fileManagerState, { ...val, sortOrder: newValue })
|
||||
},
|
||||
})
|
||||
|
||||
export const fileManagerLayout = selector({
|
||||
key: "fileManagerLayout",
|
||||
get: ({ get }) => get(fileManagerState).layout,
|
||||
set: ({ get, set }, newValue: any) => {
|
||||
const val = get(fileManagerState)
|
||||
set(fileManagerState, { ...val, layout: newValue })
|
||||
},
|
||||
})
|
||||
|
||||
export const fileManagerSearchText = selector({
|
||||
key: "fileManagerSearchText",
|
||||
get: ({ get }) => get(fileManagerState).searchText,
|
||||
set: ({ get, set }, newValue: any) => {
|
||||
const val = get(fileManagerState)
|
||||
set(fileManagerState, { ...val, searchText: newValue })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -6,3 +6,40 @@ export enum PluginName {
|
||||
RestoreFormer = "RestoreFormer",
|
||||
InteractiveSeg = "InteractiveSeg",
|
||||
}
|
||||
|
||||
export enum SortBy {
|
||||
NAME = "name",
|
||||
CTIME = "ctime",
|
||||
MTIME = "mtime",
|
||||
}
|
||||
|
||||
export enum SortOrder {
|
||||
DESCENDING = "desc",
|
||||
ASCENDING = "asc",
|
||||
}
|
||||
|
||||
export enum HDStrategy {
|
||||
ORIGINAL = "Original",
|
||||
RESIZE = "Resize",
|
||||
CROP = "Crop",
|
||||
}
|
||||
|
||||
export enum LDMSampler {
|
||||
ddim = "ddim",
|
||||
plms = "plms",
|
||||
}
|
||||
|
||||
export enum CV2Flag {
|
||||
INPAINT_NS = "INPAINT_NS",
|
||||
INPAINT_TELEA = "INPAINT_TELEA",
|
||||
}
|
||||
|
||||
export interface HDSettings {
|
||||
hdStrategy: HDStrategy
|
||||
hdStrategyResizeLimit: number
|
||||
hdStrategyCropTrigerSize: number
|
||||
hdStrategyCropMargin: number
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
export type ModelsHDSettings = { [key in AIModel]: HDSettings }
|
||||
|
||||
Reference in New Issue
Block a user