refactor theme loading

Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
Vladimir Mandic
2026-09-15 08:17:27 +02:00
parent af69cb7a88
commit 28c20f6aa0
20 changed files with 61 additions and 42 deletions
+6 -4
View File
@@ -77,7 +77,7 @@ def temp_disable_extensions():
theme_type = shared.cmd_opts.theme if shared.cmd_opts.theme is not None else shared.opts.theme_type
theme_name = f'{theme_type.lower()}/{shared.opts.gradio_theme}'
if '/' not in theme_name: # set default themes per type
if theme_name == 'standard' or theme_name == 'default':
if theme_name == 'standard':
theme_name = 'standard/black-teal'
if theme_name == 'modern':
theme_name = 'modern/Default'
@@ -86,19 +86,21 @@ def temp_disable_extensions():
if theme_name == 'huggingface':
theme_name = 'huggingface/blaaa'
if theme_name.lower().startswith('standard') or theme_name.lower().startswith('default'):
if theme_name.lower().startswith('standard'):
shared.opts.data['theme_type'] = 'Standard'
shared.opts.data['gradio_theme'] = theme_name[9:]
disabled.append('sdnext-modernui')
elif theme_name.lower().startswith('modern'):
shared.opts.data['theme_type'] = 'Modern'
shared.opts.data['gradio_theme'] = theme_name[7:]
elif theme_name.lower().startswith('huggingface') or theme_name.lower().startswith('gradio') or theme_name.lower().startswith('none'):
shared.opts.data['theme_type'] = 'None'
shared.opts.data['gradio_theme'] = theme_name
disabled.append('sdnext-modernui')
else:
log.error(f'UI theme invalid: theme="{theme_name}" available={["standard/*", "modern/*", "none/*"]} fallback="standard/black-teal"')
shared.opts.data['theme_type'] = 'Standard'
shared.opts.data['gradio_theme'] = 'black-teal'
shared.opts.data['theme_type'] = 'Modern'
shared.opts.data['gradio_theme'] = 'Default'
if shared.cmd_opts.safe:
for ext in disable_safe:
+9 -9
View File
@@ -116,19 +116,18 @@ def reload_gradio_theme():
opts.gradio_theme = theme_name
log.info(f'UI locale: name="{opts.ui_locale}"')
if theme_name.lower() in ['lobe', 'cozy-nest']:
log.info(f'UI theme extension: name="{theme_name}"')
return None
elif opts.theme_type == 'Standard':
if opts.theme_type == 'Standard':
gradio_theme = gr.themes.Base(**default_font_params)
log.info(f'UI theme: type={opts.theme_type} name="{theme_name}" available={len(available_themes)}')
log.debug(f'UI theme: type={opts.theme_type} available={len(available_themes)}')
log.warning('UI theme: please switch to ModernUI for best experience')
return 'sdnext.css'
elif opts.theme_type == 'Modern':
if opts.theme_type == 'Modern':
gradio_theme = gr.themes.Base(**default_font_params)
log.info(f'UI theme: type={opts.theme_type} name="{theme_name}" available={len(available_themes)}')
log.debug(f'UI theme: type={opts.theme_type} available={len(available_themes)}')
return 'base.css'
elif opts.theme_type == 'None':
if opts.theme_type == 'None':
if theme_name.startswith('gradio/'):
log.warning('UI theme: using Gradio default theme which is not optimized for SD.Next')
if theme_name == "gradio/default":
@@ -153,8 +152,9 @@ def reload_gradio_theme():
except Exception as e:
log.error(f"UI theme: download error accessing HuggingFace {e}")
gradio_theme = gr.themes.Default(**default_font_params)
log.info(f'UI theme: type={opts.theme_type} name="{theme_name}" style={opts.theme_style}')
log.debug(f'UI theme: type={opts.theme_type} style={opts.theme_style}')
log.warning('UI theme: please switch to ModernUI for best experience')
return 'base.css'
log.error(f'UI theme: type={opts.theme_type} unknown')
return None
+30 -13
View File
@@ -65,7 +65,7 @@ def html_login():
def html_css(css: list[str]):
def stylesheet(fn):
return f'<link rel="stylesheet" property="stylesheet" href="{webpath(fn)}">'
return f'<link rel="stylesheet" property="stylesheet" href="{webpath(fn)}">\n'
head = ''
for cssfile in css:
@@ -79,24 +79,41 @@ def html_css(css: list[str]):
head += stylesheet(cssfile)
usercss = os.path.join(data_path, "user.css") if os.path.exists(os.path.join(data_path, "user.css")) else None
if shared.opts.theme_type == 'Standard':
# themecss = os.path.join(script_path, 'javascript', f"{shared.opts.gradio_theme}.css")
themecss = os.path.join(script_path, 'ui', 'css', f"{shared.opts.gradio_theme}.css")
if os.path.exists(themecss):
head += stylesheet(themecss)
log.debug(f'UI theme: css="{themecss}" base="{css}" user="{usercss}"')
if shared.cmd_opts.theme is not None:
if shared.cmd_opts.theme.lower().startswith('standard'):
shared.opts.theme_type = 'Standard'
elif shared.cmd_opts.theme.lower().startswith('modern'):
shared.opts.theme_type = 'Modern'
else:
log.error(f'UI theme: css="{themecss}" path="{os.getcwd()}" not found')
shared.opts.theme_type = 'None'
if shared.opts.theme_type == 'Standard':
if shared.opts.gradio_theme == 'Default':
shared.opts.gradio_theme = 'black-teal'
themecss = os.path.join(script_path, 'ui', 'css', f"{shared.opts.gradio_theme}.css")
if not os.path.exists(themecss):
log.error(f'UI theme: type={shared.opts.theme_type} css="{themecss}" path="{os.getcwd()}" not found')
shared.opts.gradio_theme = 'black-teal'
themecss = os.path.join(script_path, 'ui', 'css', f"{shared.opts.gradio_theme}.css")
head += stylesheet(themecss)
log.info(f'UI theme: type={shared.opts.theme_type} css="{themecss}" base="{css}" user="{usercss}"')
elif shared.opts.theme_type == 'Modern':
if shared.opts.gradio_theme == 'black-teal':
shared.opts.gradio_theme = 'Default'
theme_folder = next((e.path for e in extensions.extensions if e.name == 'sdnext-modernui'), None)
themecss = os.path.join(theme_folder or '', 'themes', f'{shared.opts.gradio_theme}.css')
if os.path.exists(themecss):
head += stylesheet(themecss)
log.debug(f'UI theme: css="{themecss}" base="{css}" user="{usercss}"')
else:
log.error(f'UI theme: css="{themecss}" not found')
if not os.path.exists(themecss):
log.error(f'UI theme: type={shared.opts.theme_type} css="{themecss}" not found')
shared.opts.gradio_theme = 'Default'
themecss = os.path.join(theme_folder or '', 'themes', f'{shared.opts.gradio_theme}.css')
head += stylesheet(themecss)
log.info(f'UI theme: type={shared.opts.theme_type} css="{themecss}" base="{css}" user="{usercss}"')
if usercss is not None:
head += stylesheet(usercss)
return head
+2 -2
View File
@@ -1,5 +1,5 @@
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf') }
@font-face { font-family: 'Ubuntu'; font-display: swap; font-style: normal; font-weight: 100; src: local('Ubuntu'), url('fonts/ubuntu-nerdfont.ttf') }
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('notosans-nerdfont-regular.ttf') }
@font-face { font-family: 'Ubuntu'; font-display: swap; font-style: normal; font-weight: 100; src: local('Ubuntu'), url('ubuntu-nerdfont.ttf') }
/* toolbutton */
.gradio-button.tool { max-width: min-content; min-width: min-content !important; align-self: end; font-size: 1.4em; color: var(--body-text-color) !important; }
+1 -1
View File
@@ -1,5 +1,5 @@
/* generic html tags */
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf') }
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('notosans-nerdfont-regular.ttf') }
:root, .light, .dark {
--font: 'NotoSans';
--font-mono: 'ui-monospace', 'Consolas', monospace;
+1 -1
View File
@@ -1,5 +1,5 @@
/* generic html tags */
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf') }
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('notosans-nerdfont-regular.ttf') }
:root, .light, .dark {
--font: 'NotoSans';
--font-mono: 'ui-monospace', 'Consolas', monospace;
+1 -1
View File
@@ -4,7 +4,7 @@
font-display: swap;
font-style: normal;
font-weight: 100;
src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf');
src: local('NotoSansNerd'), url('notosans-nerdfont-regular.ttf');
}
html {
+1 -1
View File
@@ -1,5 +1,5 @@
/* generic html tags */
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf') }
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('notosans-nerdfont-regular.ttf') }
:root, .light, .dark {
--font: 'NotoSans';
--font-mono: 'ui-monospace', 'Consolas', monospace;
+1 -1
View File
@@ -1,5 +1,5 @@
/* generic html tags */
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf') }
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('notosans-nerdfont-regular.ttf') }
:root, .light, .dark {
--font: 'NotoSans';
--font-mono: 'ui-monospace', 'Consolas', monospace;
+2 -2
View File
@@ -3,14 +3,14 @@
font-family: 'NotoSans';
font-style: normal;
font-weight: 100;
src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf');
src: local('NotoSansNerd'), url('notosans-nerdfont-regular.ttf');
}
@font-face {
font-display: swap;
font-family: 'Ubuntu';
font-style: normal;
font-weight: 100;
src: local('Ubuntu'), url('fonts/ubuntu-nerdfont.ttf');
src: local('Ubuntu'), url('ubuntu-nerdfont.ttf');
}
:root {
+1 -1
View File
@@ -1,5 +1,5 @@
/* generic html tags */
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf') }
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('notosans-nerdfont-regular.ttf') }
:root, .light, .dark {
--font: 'NotoSans';
--font-mono: 'ui-monospace', 'Consolas', monospace;
+1 -1
View File
@@ -1,5 +1,5 @@
/* generic html tags */
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('fonts/notosans-nerdfont-regular.ttf') }
@font-face { font-family: 'NotoSans'; font-display: swap; font-style: normal; font-weight: 100; src: local('NotoSansNerd'), url('notosans-nerdfont-regular.ttf') }
:root, .light, .dark {
--font: 'NotoSans';
--font-mono: 'ui-monospace', 'Consolas', monospace;
Binary file not shown.
+1 -1
View File
@@ -16218,7 +16218,7 @@ async function initStartup() {
await waitForOpts();
await updateSubpath();
executeCallbacks(uiReadyCallbacks);
if (window.waitForUiReady) await window.waitForUiReady();
if (window.opts.theme_type.toLowerCase().startsWith("modern") && window.waitForUiReady) await window.waitForUiReady();
startupPromises.push(Promise.resolve(initLogMonitor()));
startupPromises.push(Promise.resolve(setRefreshInterval()));
startupPromises.push(Promise.resolve(setupExtraNetworks()));
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -102,7 +102,7 @@ export async function initStartup() {
executeCallbacks(uiReadyCallbacks);
// optionally wait for modern ui
if (window.waitForUiReady) await window.waitForUiReady();
if (window.opts.theme_type.toLowerCase().startsWith('modern') && window.waitForUiReady) await window.waitForUiReady();
// post startup tasks that may take longer but are not critical
startupPromises.push(Promise.resolve(initLogMonitor()));