1
0
Fork 0

feat(gui): make status update interval configurable

This commit is contained in:
Sean Sube 2024-01-14 08:50:03 -06:00
parent d349e8cc10
commit 80f3438ebd
Signed by: ssube
GPG Key ID: 3EED7B957D362AF1
9 changed files with 48 additions and 27 deletions

View File

@ -1,9 +1,9 @@
/* eslint-disable max-lines */
import { doesExist, InvalidArgumentError, Maybe } from '@apextoaster/js-utils';
import { create as batcher, windowScheduler, keyResolver } from '@yornaath/batshit';
import { create as batcher, keyResolver, windowScheduler } from '@yornaath/batshit';
import { ServerParams } from '../config.js';
import { FIXED_FLOAT, FIXED_INTEGER, POLL_TIME, STATUS_SUCCESS } from '../constants.js';
import { FIXED_FLOAT, FIXED_INTEGER, STATUS_SUCCESS } from '../constants.js';
import { JobResponse, JobResponseWithRetry, SuccessJobResponse } from '../types/api-v2.js';
import {
FilterResponse,
@ -125,7 +125,7 @@ export function appendHighresToURL(url: URL, highres: HighresParams) {
/**
* Make an API client using the given API root and fetch client.
*/
export function makeClient(root: string, token: Maybe<string> = undefined, f = fetch): ApiClient {
export function makeClient(root: string, batchInterval: number, token: Maybe<string> = undefined, f = fetch): ApiClient {
function parseRequest(url: URL, options: RequestInit): Promise<JobResponse> {
return f(url, options).then((res) => parseJobResponse(root, res));
}
@ -505,7 +505,7 @@ export function makeClient(root: string, token: Maybe<string> = undefined, f = f
const batchStatus = batcher({
fetcher: async (jobs: Array<string>) => client.status(jobs),
resolver: keyResolver('name'),
scheduler: windowScheduler(POLL_TIME),
scheduler: windowScheduler(batchInterval),
});
return {

View File

@ -48,14 +48,16 @@ export function newSeed(): number {
return Math.floor(Math.random() * MAX_SEED);
}
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
export const RANDOM_SEED = [-1, '-1'];
export function replaceRandomSeeds(key: string, values: Array<number | string>): Array<number | string> {
if (key !== 'seed') {
return values;
}
return values.map((it) => {
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
if (it === '-1' || it === -1) {
if (RANDOM_SEED.includes(it)) {
return newSeed();
}
@ -108,8 +110,8 @@ export function makeTxt2ImgGridPipeline(
defaults: {
...model,
...params,
...(upscale || {}),
...(highres || {}),
...(upscale ?? {}),
...(highres ?? {}),
},
stages: [],
};

View File

@ -8,10 +8,11 @@ import { useTranslation } from 'react-i18next';
import { useStore } from 'zustand';
import { shallow } from 'zustand/shallow';
import { POLL_TIME, STANDARD_SPACING } from '../../constants.js';
import { STANDARD_SPACING } from '../../constants.js';
import { ClientContext, ConfigContext, OnnxState, StateContext } from '../../state/full.js';
import { JobResponse, JobStatus } from '../../types/api-v2.js';
import { visibleIndex } from '../../utils.js';
import { getBatchInterval } from '../utils.js';
const LOADING_PERCENT = 100;
const LOADING_OVERAGE = 99;
@ -22,6 +23,7 @@ export interface LoadingCardProps {
export function LoadingCard(props: LoadingCardProps) {
const { image } = props;
const batch = getBatchInterval();
const client = mustExist(useContext(ClientContext));
const { params } = mustExist(useContext(ConfigContext));
@ -34,7 +36,7 @@ export function LoadingCard(props: LoadingCardProps) {
const ready = useQuery(['ready', image.name], () => client.status([image.name]), {
// data will always be ready without this, even if the API says its not
cacheTime: 0,
refetchInterval: POLL_TIME,
refetchInterval: batch,
});
function renderProgress() {

View File

@ -55,7 +55,7 @@ export function Settings() {
max={6}
step={1}
value={state.historyWidth}
onChange={(value) => state.setWidth(value)}
onChange={(value) => state.setHistoryWidth(value)}
/>
<Button variant='contained' onClick={() => state.setLayout(state.layout === 'horizontal' ? 'vertical' : 'horizontal')}>Toggle Layout</Button>
<TextField variant='outlined' label={t('setting.prompt')} value={state.defaults.prompt} onChange={(event) => {

View File

@ -1,3 +1,4 @@
import { Maybe, doesExist } from '@apextoaster/js-utils';
import { PaletteMode } from '@mui/material';
import { Theme } from '../state/types.js';
@ -31,3 +32,18 @@ export function getTheme(currentTheme: Theme, preferDark: boolean): PaletteMode
}
return currentTheme as PaletteMode;
}
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
export function getBatchInterval(defaultInterval = 5000): number {
const query = new URLSearchParams(window.location.search);
const interval = query.get('interval');
if (doesExist(interval)) {
return parseInt(interval, 10);
}
return defaultInterval;
}
export function getToken(): Maybe<string> {
const query = new URLSearchParams(window.location.search);
return query.get('token');
}

View File

@ -123,14 +123,15 @@ export function getApiRoot(config: Config): string {
}
}
export const TRUE_VALUES = ['1', 't', 'true', 'y', 'yes'];
export function isDebug(): boolean {
const query = new URLSearchParams(window.location.search);
const debug = query.get('debug');
if (doesExist(debug)) {
const val = debug.toLowerCase();
// eslint-disable-next-line no-restricted-syntax
return val === '1' || val === 't' || val === 'true' || val === 'y' || val === 'yes';
return TRUE_VALUES.includes(val);
} else {
return false;
}

View File

@ -73,7 +73,6 @@ export const LAYOUT_STYLES = {
export const INITIAL_LOAD_TIMEOUT = 5_000;
export const STALE_TIME = 300_000; // 5 minutes
export const POLL_TIME = 5_000; // 5 seconds
export const SAVE_TIME = 5_000; // 5 seconds
export const IMAGE_FILTER = '.bmp, .jpg, .jpeg, .png';

View File

@ -11,14 +11,16 @@ import { createStore } from 'zustand';
import { createJSONStorage, persist } from 'zustand/middleware';
import { makeClient } from './client/api.js';
import { LOCAL_CLIENT } from './client/local.js';
import { ApiClient } from './client/base.js';
import { LOCAL_CLIENT } from './client/local.js';
import { ParamsVersionError } from './components/error/ParamsVersion.js';
import { ServerParamsError } from './components/error/ServerParams.js';
import { LoadingScreen } from './components/LoadingScreen.js';
import { OnnxError } from './components/OnnxError.js';
import { OnnxWeb } from './components/OnnxWeb.js';
import { getBatchInterval, getToken } from './components/utils.js';
import { Config, getApiRoot, isDebug, loadConfig, mergeConfig, ServerParams } from './config.js';
import { INITIAL_LOAD_TIMEOUT, PARAM_VERSION } from './constants.js';
import {
ClientContext,
ConfigContext,
@ -29,9 +31,8 @@ import {
STATE_VERSION,
StateContext,
} from './state/full.js';
import { I18N_STRINGS } from './strings/all.js';
import { applyStateMigrations, UnknownState } from './state/migration/default.js';
import { INITIAL_LOAD_TIMEOUT, PARAM_VERSION } from './constants.js';
import { I18N_STRINGS } from './strings/all.js';
export async function renderApp(config: Config, params: ServerParams, logger: Logger, client: ApiClient) {
const completeConfig = mergeConfig(config, params);
@ -149,13 +150,13 @@ export async function main() {
// load config from GUI server
const config = await loadConfig();
// get token from query string
const query = new URLSearchParams(window.location.search);
const token = query.get('token');
// get client params from query string
const root = getApiRoot(config);
const batch = getBatchInterval();
const token = getToken();
// use that to create an API client
const root = getApiRoot(config);
const client = makeClient(root, token);
const client = makeClient(root, batch, token);
// prep react-dom
const appElement = mustExist(document.getElementById('app'));

View File

@ -2,7 +2,7 @@ import { Slice } from './types.js';
export type Layout = 'horizontal' | 'vertical';
export const DEFAULT_LAYOUT = {
export const DEFAULT_SETTINGS = {
historyWidth: 4,
layout: 'vertical' as Layout,
} as const;
@ -11,23 +11,23 @@ export interface SettingsSlice {
historyWidth: number;
layout: Layout;
setHistoryWidth(width: number): void;
setLayout(layout: Layout): void;
setWidth(width: number): void;
}
export function createSettingsSlice<TState extends SettingsSlice>(): Slice<TState, SettingsSlice> {
return (set) => ({
...DEFAULT_LAYOUT,
...DEFAULT_SETTINGS,
setLayout(layout) {
set((prev) => ({
...prev,
layout,
}));
},
setWidth(width) {
setHistoryWidth(historyWidth) {
set((prev) => ({
...prev,
historyWidth: width,
historyWidth,
}));
},
});