✨ feat: Fit SD WebUI 1.9
parent
77102c0e1e
commit
3e01da0cea
|
|
@ -10,7 +10,7 @@ module.exports = {
|
||||||
entryLocale: 'en_US',
|
entryLocale: 'en_US',
|
||||||
output: 'locales',
|
output: 'locales',
|
||||||
outputLocales: outputLocales,
|
outputLocales: outputLocales,
|
||||||
modelName: 'gpt-3.5-turbo-1106',
|
modelName: 'gpt-3.5-turbo-0125',
|
||||||
experimental: {
|
experimental: {
|
||||||
jsonMode: true,
|
jsonMode: true,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -25,6 +25,7 @@
|
||||||
"title": "Themenfeedback"
|
"title": "Themenfeedback"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
|
"desc": "Einstellungen für Thema und Layout",
|
||||||
"title": "Themen-Einstellungen"
|
"title": "Themen-Einstellungen"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"brand": {
|
"brand": {
|
||||||
|
"custom": "Custom",
|
||||||
"kitchen": "Kitchen",
|
"kitchen": "Kitchen",
|
||||||
"lobe": "LobeHub",
|
"lobe": "LobeHub"
|
||||||
"custom": "Custom"
|
|
||||||
},
|
},
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"confirm": "Confirm",
|
"confirm": "Confirm",
|
||||||
|
|
@ -10,34 +10,35 @@
|
||||||
"initializing": "StableDiffusion / LobeTheme is initializing, please wait..."
|
"initializing": "StableDiffusion / LobeTheme is initializing, please wait..."
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"resources": "Resources",
|
|
||||||
"community": "Community",
|
"community": "Community",
|
||||||
"help": "Help",
|
"help": "Help",
|
||||||
"moreProducts": "More Products"
|
"moreProducts": "More Products",
|
||||||
|
"resources": "Resources"
|
||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"feedback": "Feedback",
|
"feedback": "Feedback",
|
||||||
"switchTheme": "Switch Light/Dark Theme",
|
"setting": "Setting",
|
||||||
"setting": "Setting"
|
"switchTheme": "Switch Light/Dark Theme"
|
||||||
},
|
},
|
||||||
"modal": {
|
"modal": {
|
||||||
"themeFeedback": {
|
"themeFeedback": {
|
||||||
"title": "Theme Feedback"
|
"title": "Theme Feedback"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
|
"desc": "Preferences and Layout Settings",
|
||||||
"title": "Theme Settings"
|
"title": "Theme Settings"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"area": {
|
"area": {
|
||||||
"object": "Object Selection",
|
|
||||||
"attribute": "Attribute Selection",
|
"attribute": "Attribute Selection",
|
||||||
|
"object": "Object Selection",
|
||||||
"tag": "Tag Selection"
|
"tag": "Tag Selection"
|
||||||
},
|
},
|
||||||
"load": "Load Prompt",
|
"load": "Load Prompt",
|
||||||
"set": "Set Prompt",
|
|
||||||
"negative": "Negative",
|
"negative": "Negative",
|
||||||
"positive": "Positive"
|
"positive": "Positive",
|
||||||
|
"set": "Set Prompt"
|
||||||
},
|
},
|
||||||
"setting": {
|
"setting": {
|
||||||
"button": {
|
"button": {
|
||||||
|
|
@ -45,152 +46,152 @@
|
||||||
"submit": "Apply and Restart Interface"
|
"submit": "Apply and Restart Interface"
|
||||||
},
|
},
|
||||||
"confirmPageUnload": {
|
"confirmPageUnload": {
|
||||||
"title": "Confirmation on page leaving",
|
"desc": "Helps prevent loss of unsaved data",
|
||||||
"desc": "Helps prevent loss of unsaved data"
|
"title": "Confirmation on page leaving"
|
||||||
},
|
},
|
||||||
"customFont": {
|
"customFont": {
|
||||||
"title": "Custom Font",
|
"desc": "When enabled, it will automatically load a webfont to enhance the display of text in Chinese, English, and code",
|
||||||
"desc": "When enabled, it will automatically load a webfont to enhance the display of text in Chinese, English, and code"
|
"title": "Custom Font"
|
||||||
},
|
},
|
||||||
"customLogo": {
|
"customLogo": {
|
||||||
"title": "Custom Logo",
|
"desc": "Support URL / Base64 / Emoji symbols",
|
||||||
"desc": "Support URL / Base64 / Emoji symbols"
|
"title": "Custom Logo"
|
||||||
},
|
},
|
||||||
"customTitle": {
|
"customTitle": {
|
||||||
"title": "Custom Title",
|
"desc": "Custom Logo Title",
|
||||||
"desc": "Custom Logo Title"
|
"title": "Custom Title"
|
||||||
},
|
},
|
||||||
"extraNetworkSidebar": {
|
"extraNetworkSidebar": {
|
||||||
"defaultCardSize": {
|
"defaultCardSize": {
|
||||||
"title": "Model Cover Size",
|
"desc": "Default value of model cover size when starting",
|
||||||
"desc": "Default value of model cover size when starting"
|
"title": "Model Cover Size"
|
||||||
},
|
},
|
||||||
"defaultExpand": {
|
"defaultExpand": {
|
||||||
"title": "Default Expand",
|
"desc": "Whether to expand the sidebar by default when starting",
|
||||||
"desc": "Whether to expand the sidebar by default when starting"
|
"title": "Default Expand"
|
||||||
},
|
},
|
||||||
"defaultWidth": {
|
"defaultWidth": {
|
||||||
"title": "Default Width",
|
"desc": "Default width of the sidebar when starting",
|
||||||
"desc": "Default width of the sidebar when starting"
|
"title": "Default Width"
|
||||||
},
|
},
|
||||||
"displayMode": {
|
"displayMode": {
|
||||||
"title": "Display Mode",
|
"desc": "Fixed as grid mode for constant display, auto-expand when the mouse moves to the side in floating mode",
|
||||||
"desc": "Fixed as grid mode for constant display, auto-expand when the mouse moves to the side in floating mode"
|
"title": "Display Mode"
|
||||||
},
|
},
|
||||||
"enable": {
|
"enable": {
|
||||||
"title": "Enable",
|
"desc": "Enable the extra network sidebar on the right side",
|
||||||
"desc": "Enable the extra network sidebar on the right side"
|
"title": "Enable"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tab": {
|
|
||||||
"appearance": "Appearance",
|
|
||||||
"sidebar": "Sidebar",
|
|
||||||
"layout": "Layout",
|
|
||||||
"experimental": "Experimental"
|
|
||||||
},
|
|
||||||
"group": {
|
"group": {
|
||||||
|
"experimental": "Experimental Features",
|
||||||
"extraNetworkSidebar": "Extra Network Sidebar",
|
"extraNetworkSidebar": "Extra Network Sidebar",
|
||||||
"layout": "Layout Settings",
|
"layout": "Layout Settings",
|
||||||
"promptTextarea": "Prompt Textbox",
|
"promptTextarea": "Prompt Textbox",
|
||||||
"quickSettingSidebar": "Quick Setting Sidebar",
|
"quickSettingSidebar": "Quick Setting Sidebar",
|
||||||
"theme": "Theme Settings",
|
"theme": "Theme Settings"
|
||||||
"experimental": "Experimental Features"
|
|
||||||
},
|
|
||||||
"imageInfo": {
|
|
||||||
"title": "Image Info Alternative",
|
|
||||||
"desc": "Display better image information in the generated image"
|
|
||||||
},
|
},
|
||||||
"hideFooter": {
|
"hideFooter": {
|
||||||
"title": "Hide Footer",
|
"desc": "Hide the theme footer and only display the default footer of stable diffusion webui",
|
||||||
"desc": "Hide the theme footer and only display the default footer of stable diffusion webui"
|
"title": "Hide Footer"
|
||||||
|
},
|
||||||
|
"imageInfo": {
|
||||||
|
"desc": "Display better image information in the generated image",
|
||||||
|
"title": "Image Info Alternative"
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"title": "Language",
|
"desc": "Lobe Theme language",
|
||||||
"desc": "Lobe Theme language"
|
"title": "Language"
|
||||||
},
|
},
|
||||||
"logoType": {
|
"logoType": {
|
||||||
"title": "Logo Type",
|
|
||||||
"desc": "Logo Type",
|
"desc": "Logo Type",
|
||||||
"preview": "Preview"
|
"preview": "Preview",
|
||||||
|
"title": "Logo Type"
|
||||||
},
|
},
|
||||||
"neutralColor": {
|
"neutralColor": {
|
||||||
"title": "Neutral Color",
|
"desc": "Customize different shades of gray with different color tendencies, the second one is the original Kitchen neutral color",
|
||||||
"desc": "Customize different shades of gray with different color tendencies, the second one is the original Kitchen neutral color"
|
"title": "Neutral Color"
|
||||||
},
|
},
|
||||||
"primaryColor": {
|
"primaryColor": {
|
||||||
"title": "Primary Color",
|
"desc": "Custom primary color, the second one is the original Kitchen theme color",
|
||||||
"desc": "Custom primary color, the second one is the original Kitchen theme color"
|
"title": "Primary Color"
|
||||||
},
|
},
|
||||||
"promptDisplayMode": {
|
"promptDisplayMode": {
|
||||||
"title": "Prompt Display Mode",
|
|
||||||
"desc": "Fixed height or auto height with draggable resize support",
|
"desc": "Fixed height or auto height with draggable resize support",
|
||||||
"resizable": "Resizable",
|
"resizable": "Resizable",
|
||||||
"scroll": "Scroll"
|
"scroll": "Scroll",
|
||||||
|
"title": "Prompt Display Mode"
|
||||||
},
|
},
|
||||||
"promptEditor": {
|
"promptEditor": {
|
||||||
"title": "Prompt Editor",
|
"desc": "Provide a simple prompt editor at the top of the quick setting sidebar",
|
||||||
"desc": "Provide a simple prompt editor at the top of the quick setting sidebar"
|
"title": "Prompt Editor"
|
||||||
},
|
},
|
||||||
"promptHighlight": {
|
"promptHighlight": {
|
||||||
"title": "Prompt Syntax Highlighting",
|
"desc": "Automatically colorize prompt display according to the Stable Diffusion syntax rules",
|
||||||
"desc": "Automatically colorize prompt display according to the Stable Diffusion syntax rules"
|
"title": "Prompt Syntax Highlighting"
|
||||||
},
|
},
|
||||||
"quickSettingSidebar": {
|
"quickSettingSidebar": {
|
||||||
"defaultExpand": {
|
"defaultExpand": {
|
||||||
"title": "Default Expand",
|
"desc": "Whether to expand the sidebar by default when starting",
|
||||||
"desc": "Whether to expand the sidebar by default when starting"
|
"title": "Default Expand"
|
||||||
},
|
},
|
||||||
"defaultWidth": {
|
"defaultWidth": {
|
||||||
"title": "Default Width",
|
"desc": "Default width of the sidebar when starting",
|
||||||
"desc": "Default width of the sidebar when starting"
|
"title": "Default Width"
|
||||||
},
|
},
|
||||||
"displayMode": {
|
"displayMode": {
|
||||||
"title": "Display Mode",
|
"desc": "Fixed as grid mode for constant display, auto-expand when the mouse moves to the side in floating mode",
|
||||||
"desc": "Fixed as grid mode for constant display, auto-expand when the mouse moves to the side in floating mode"
|
"title": "Display Mode"
|
||||||
},
|
},
|
||||||
"enable": {
|
"enable": {
|
||||||
"title": "Enable",
|
"desc": "Enable the quick setting sidebar on the left side",
|
||||||
"desc": "Enable the quick setting sidebar on the left side"
|
"title": "Enable"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"reduceAnimation": {
|
"reduceAnimation": {
|
||||||
"title": "Reduce Animation",
|
"desc": "Reduce the blur effect and background flow color, which can improve smoothness and save CPU usage",
|
||||||
"desc": "Reduce the blur effect and background flow color, which can improve smoothness and save CPU usage"
|
"title": "Reduce Animation"
|
||||||
},
|
},
|
||||||
"splitPreviewer": {
|
"splitPreviewer": {
|
||||||
"title": "Split Previewer",
|
"desc": "Put the prompt input box on the left and the generate button on the right, ensuring that the generated image is always displayed at the top when scrolling (experimental)",
|
||||||
"desc": "Put the prompt input box on the left and the generate button on the right, ensuring that the generated image is always displayed at the top when scrolling (experimental)"
|
"title": "Split Previewer"
|
||||||
},
|
},
|
||||||
"svgIcons": {
|
"svgIcons": {
|
||||||
"title": "SVG Icons",
|
"desc": "Replace all Emoji icons in stable diffusion webui with SVG icons globally",
|
||||||
"desc": "Replace all Emoji icons in stable diffusion webui with SVG icons globally"
|
"title": "SVG Icons"
|
||||||
|
},
|
||||||
|
"tab": {
|
||||||
|
"appearance": "Appearance",
|
||||||
|
"experimental": "Experimental",
|
||||||
|
"layout": "Layout",
|
||||||
|
"sidebar": "Sidebar"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"share": "Share",
|
"share": "Share",
|
||||||
"shareModal": {
|
"shareModal": {
|
||||||
"download": "Download Screenshot",
|
"download": "Download Screenshot",
|
||||||
"imageType": "Image Format",
|
"imageType": "Image Format",
|
||||||
"screenshot": "Screenshot",
|
|
||||||
"info": "Image Info",
|
"info": "Image Info",
|
||||||
|
"screenshot": "Screenshot",
|
||||||
"settings": "Export Settings",
|
"settings": "Export Settings",
|
||||||
"withBackground": "Include Background Image",
|
|
||||||
"withFooter": "Include Footer",
|
|
||||||
"warn": "Please Generate Image First",
|
|
||||||
"showNegative": "Show Negative Promot",
|
|
||||||
"showConfig": "Show Generate Config",
|
|
||||||
"showAllImages": "Show All Images",
|
"showAllImages": "Show All Images",
|
||||||
"title": "Image Name",
|
"showConfig": "Show Generate Config",
|
||||||
|
"showNegative": "Show Negative Promot",
|
||||||
"tabs": {
|
"tabs": {
|
||||||
"info": "Info",
|
"info": "Info",
|
||||||
"settings": "Settings"
|
"settings": "Settings"
|
||||||
}
|
},
|
||||||
|
"title": "Image Name",
|
||||||
|
"warn": "Please Generate Image First",
|
||||||
|
"withBackground": "Include Background Image",
|
||||||
|
"withFooter": "Include Footer"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"extraNetwork": "Extra Network",
|
"extraNetwork": "Extra Network",
|
||||||
"quickSetting": "Quick Setting",
|
|
||||||
"mode": {
|
"mode": {
|
||||||
"fixed": "Fixed",
|
"fixed": "Fixed",
|
||||||
"float": "Float"
|
"float": "Float"
|
||||||
}
|
},
|
||||||
|
"quickSetting": "Quick Setting"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"title": "Comentarios sobre el tema"
|
"title": "Comentarios sobre el tema"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
|
"desc": "Preferencias y configuración de diseño",
|
||||||
"title": "Configuración del tema"
|
"title": "Configuración del tema"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"title": "Retour sur le thème"
|
"title": "Retour sur le thème"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
|
"desc": "Paramètres de thème et de mise en page",
|
||||||
"title": "Paramètres du thème"
|
"title": "Paramètres du thème"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"title": "テーマフィードバック"
|
"title": "テーマフィードバック"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
|
"desc": "テーマとレイアウト設定",
|
||||||
"title": "テーマ設定"
|
"title": "テーマ設定"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"title": "테마 피드백"
|
"title": "테마 피드백"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
|
"desc": "테마 및 레이아웃 설정",
|
||||||
"title": "테마 설정"
|
"title": "테마 설정"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"title": "Feedback do Tema"
|
"title": "Feedback do Tema"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
|
"desc": "Preferências e configurações de layout",
|
||||||
"title": "Configurações do Tema"
|
"title": "Configurações do Tema"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"title": "Обратная связь по теме"
|
"title": "Обратная связь по теме"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
|
"desc": "Настройки темы и макета",
|
||||||
"title": "Настройки темы"
|
"title": "Настройки темы"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"title": "Tema Geri Bildirimi"
|
"title": "Tema Geri Bildirimi"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
|
"desc": "Tema ve Düzen Ayarları",
|
||||||
"title": "Tema Ayarları"
|
"title": "Tema Ayarları"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@
|
||||||
"title": "主题反馈"
|
"title": "主题反馈"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
"title": "主题设置"
|
"title": "主题设置",
|
||||||
|
"desc": "偏好与布局设置"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"prompt": {
|
"prompt": {
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
"title": "主題反饋"
|
"title": "主題反饋"
|
||||||
},
|
},
|
||||||
"themeSetting": {
|
"themeSetting": {
|
||||||
|
"desc": "偏好與版面設定",
|
||||||
"title": "主題設置"
|
"title": "主題設置"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
117
package.json
117
package.json
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "sd-webui-lobe-theme",
|
"name": "sd-webui-lobe-theme",
|
||||||
"version": "3.4.10",
|
"version": "3.4.10",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "The modern theme for stable diffusion webui, exquisite interface design, highly customizable UI, and efficiency boosting features.",
|
"description": "LobeThem: The Modern Theme for Stable Diffusion WebUI, Exquisite interface design, Highly customizable UI, and Efficiency boosting features.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"lobehub",
|
"lobehub",
|
||||||
"stable-diffusion-webui",
|
"stable-diffusion-webui",
|
||||||
|
|
@ -67,67 +67,68 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bluelovers/auto1111-pnginfo": "^2.0.1",
|
"@bluelovers/auto1111-pnginfo": "^2.0.2",
|
||||||
"@lobehub/ui": "latest",
|
"@lobehub/ui": "^1.138.24",
|
||||||
"@rollup/rollup-win32-x64-msvc": "^4.13.0",
|
"@rollup/rollup-win32-x64-msvc": "^4.17.2",
|
||||||
"ahooks": "^3",
|
"ahooks": "^3.7.11",
|
||||||
"antd": "^5",
|
"antd": "5.17.0",
|
||||||
"antd-style": "latest",
|
"antd-style": "^3.6.2",
|
||||||
"consola": "^3",
|
"consola": "^3.2.3",
|
||||||
"dayjs": "^1",
|
"dayjs": "^1.11.11",
|
||||||
"i18next": "^23",
|
"i18next": "^23.11.4",
|
||||||
"i18next-http-backend": "^2",
|
"i18next-http-backend": "^2.5.1",
|
||||||
"lodash-es": "^4",
|
"lodash-es": "^4.17.21",
|
||||||
"lucide-react": "latest",
|
"lucide-react": "latest",
|
||||||
"lucide-static": "latest",
|
"lucide-static": "latest",
|
||||||
"modern-screenshot": "^4",
|
"modern-screenshot": "^4.4.39",
|
||||||
"polished": "^4",
|
"polished": "^4.3.1",
|
||||||
"react": "^18",
|
"react": "^18.3.1",
|
||||||
"react-dnd": "^16",
|
"react-dnd": "^16.0.1",
|
||||||
"react-dnd-html5-backend": "^16",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18.3.1",
|
||||||
"react-helmet": "^6",
|
"react-helmet": "^6.1.0",
|
||||||
"react-i18next": "^13",
|
"react-i18next": "^13.5.0",
|
||||||
"react-layout-kit": "^1",
|
"react-layout-kit": "^1.9.0",
|
||||||
"react-rnd": "^10",
|
"react-rnd": "^10.4.10",
|
||||||
"react-tag-input": "^6",
|
"react-tag-input": "^6.9.0",
|
||||||
"semver": "^7",
|
"semver": "^7.6.2",
|
||||||
"shikiji": "^0.9",
|
"shikiji": "^0.9.19",
|
||||||
"swr": "^2",
|
"swr": "^2.2.5",
|
||||||
"zustand": "^4.4.1",
|
"url-join": "^5.0.0",
|
||||||
"zustand-utils": "^1.3.1"
|
"zustand": "^4.5.2",
|
||||||
|
"zustand-utils": "^1.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^18",
|
"@commitlint/cli": "^18.6.1",
|
||||||
"@lobehub/lint": "latest",
|
"@lobehub/lint": "^1.23.4",
|
||||||
"@testing-library/jest-dom": "^6",
|
"@testing-library/jest-dom": "^6.4.5",
|
||||||
"@testing-library/react": "^14",
|
"@testing-library/react": "^14.3.1",
|
||||||
"@types/lodash-es": "^4",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20.12.12",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18.3.2",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@types/react-helmet": "^6",
|
"@types/react-helmet": "^6.1.11",
|
||||||
"@types/react-tag-input": "^6",
|
"@types/react-tag-input": "^6.6.6",
|
||||||
"@types/semver": "^7",
|
"@types/semver": "^7.5.8",
|
||||||
"@vitejs/plugin-react-swc": "^3",
|
"@vitejs/plugin-react-swc": "^3.6.0",
|
||||||
"@vitest/coverage-v8": "^1",
|
"@vitest/coverage-v8": "^1.6.0",
|
||||||
"commitlint": "^18",
|
"commitlint": "^18.6.1",
|
||||||
"dotenv": "^16",
|
"dotenv": "^16.4.5",
|
||||||
"eslint": "^8",
|
"eslint": "^8.57.0",
|
||||||
"fast-deep-equal": "^3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"husky": "^8",
|
"husky": "^8.0.3",
|
||||||
"jsdom": "^23.0.0",
|
"jsdom": "^23.2.0",
|
||||||
"lint-staged": "^15",
|
"lint-staged": "^15.2.2",
|
||||||
"prettier": "^3",
|
"prettier": "^3.2.5",
|
||||||
"query-string": "^8",
|
"query-string": "^8.2.0",
|
||||||
"remark": "^14",
|
"remark": "^14.0.3",
|
||||||
"remark-cli": "^11",
|
"remark-cli": "^11.0.0",
|
||||||
"semantic-release": "^21",
|
"semantic-release": "^21.1.2",
|
||||||
"stylelint": "^15",
|
"stylelint": "^15.11.0",
|
||||||
"terser": "^5",
|
"terser": "^5.31.0",
|
||||||
"typescript": "^5",
|
"typescript": "^5.4.5",
|
||||||
"vite": "^5",
|
"vite": "^5.2.11",
|
||||||
"vitest": "latest"
|
"vitest": "~1.2.2"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public",
|
"access": "public",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { LayoutHeader, LayoutMain, LayoutSidebar } from '@lobehub/ui';
|
||||||
import isEqual from 'fast-deep-equal';
|
import isEqual from 'fast-deep-equal';
|
||||||
import { memo, useEffect } from 'react';
|
import { memo, useEffect } from 'react';
|
||||||
|
|
||||||
|
import StructuredData from '@/components/StructuredData';
|
||||||
import PromptFormator from '@/features/PromptFormator';
|
import PromptFormator from '@/features/PromptFormator';
|
||||||
import '@/locales/config';
|
import '@/locales/config';
|
||||||
import ImageInfo from '@/modules/ImageInfo/page';
|
import ImageInfo from '@/modules/ImageInfo/page';
|
||||||
|
|
@ -35,6 +36,7 @@ const Index = memo(() => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<StructuredData />
|
||||||
<GlobalStyle />
|
<GlobalStyle />
|
||||||
<LayoutHeader headerHeight={HEADER_HEIGHT}>
|
<LayoutHeader headerHeight={HEADER_HEIGHT}>
|
||||||
<Header />
|
<Header />
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ export const Layout = memo<PropsWithChildren>(({ children }) => {
|
||||||
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, viewport-fit=cover, user-scalable=no"
|
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, viewport-fit=cover, user-scalable=no"
|
||||||
name="viewport"
|
name="viewport"
|
||||||
/>
|
/>
|
||||||
|
<title>{TITLE}</title>
|
||||||
<meta content={TITLE} name="apple-mobile-web-app-title" />
|
<meta content={TITLE} name="apple-mobile-web-app-title" />
|
||||||
<meta content={TITLE} name="application-name" />
|
<meta content={TITLE} name="application-name" />
|
||||||
<meta content={DESC} name="description" />
|
<meta content={DESC} name="description" />
|
||||||
|
|
@ -76,7 +77,29 @@ export const Layout = memo<PropsWithChildren>(({ children }) => {
|
||||||
<meta content="yes" name="apple-mobile-web-app-capable" />
|
<meta content="yes" name="apple-mobile-web-app-capable" />
|
||||||
<meta content={TITLE} name="apple-mobile-web-app-title" />
|
<meta content={TITLE} name="apple-mobile-web-app-title" />
|
||||||
<meta content="black-translucent" name="apple-mobile-web-app-status-bar-style" />
|
<meta content="black-translucent" name="apple-mobile-web-app-status-bar-style" />
|
||||||
|
<meta content={TITLE} name="apple-mobile-web-app-title" />
|
||||||
|
<meta content="yes" name="apple-mobile-web-app-capable" />
|
||||||
|
<meta content="index,follow" name="robots" />
|
||||||
<link href={manifest(genAssets)} rel="manifest" />
|
<link href={manifest(genAssets)} rel="manifest" />
|
||||||
|
<meta content={TITLE} property="og:title" />
|
||||||
|
<meta content={DESC} property="og:description" />
|
||||||
|
<meta content="https://github.com/lobehub/sd-webui-lobe-theme" property="og:url" />
|
||||||
|
<meta content={TITLE} property="og:site_name" />
|
||||||
|
<meta content="en-US" property="og:locale" />
|
||||||
|
<meta
|
||||||
|
content="https://repository-images.githubusercontent.com/606329910/7fd79db5-fd91-450c-9e95-8ccce8ffdc0b"
|
||||||
|
property="og:image"
|
||||||
|
/>
|
||||||
|
<meta content="website" property="og:type" />
|
||||||
|
<meta content="summary_large_image" name="twitter:card" />
|
||||||
|
<meta content="@lobehub" name="twitter:site" />
|
||||||
|
<meta content={TITLE} name="twitter:title" />
|
||||||
|
<meta content={DESC} name="twitter:description" />
|
||||||
|
<meta
|
||||||
|
content="https://repository-images.githubusercontent.com/606329910/7fd79db5-fd91-450c-9e95-8ccce8ffdc0b"
|
||||||
|
name="twitter:image"
|
||||||
|
/>
|
||||||
|
<link href="https://github.com/lobehub/sd-webui-lobe-theme" rel="canonical" />
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<GlobalLayout>
|
<GlobalLayout>
|
||||||
{storeLoading === false && loading === false ? children : <Loading />}
|
{storeLoading === false && loading === false ? children : <Loading />}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { FC } from 'react';
|
||||||
|
|
||||||
|
import pkg from '@/../package.json';
|
||||||
|
import { ldModule } from '@/components/StructuredData/ld';
|
||||||
|
|
||||||
|
const TITLE = 'Stable Diffusion · LobeHub';
|
||||||
|
const DESC = pkg.description;
|
||||||
|
|
||||||
|
const StructuredData: FC = () => {
|
||||||
|
const ld = ldModule.generate({
|
||||||
|
description: DESC,
|
||||||
|
image:
|
||||||
|
'https://repository-images.githubusercontent.com/606329910/7fd79db5-fd91-450c-9e95-8ccce8ffdc0b',
|
||||||
|
title: TITLE,
|
||||||
|
url: '/',
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<script
|
||||||
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(ld) }}
|
||||||
|
id="structured-data"
|
||||||
|
type="application/ld+json"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default StructuredData;
|
||||||
|
|
@ -0,0 +1,216 @@
|
||||||
|
import urlJoin from 'url-join';
|
||||||
|
|
||||||
|
import pkg from '@/../package.json';
|
||||||
|
import { EMAIL_BUSINESS, EMAIL_SUPPORT, OFFICIAL_SITE, SITE_URL, X } from '@/const/url';
|
||||||
|
|
||||||
|
const LAST_MODIFIED = new Date().toISOString();
|
||||||
|
export const AUTHOR_LIST = {
|
||||||
|
arvinxx: {
|
||||||
|
avatar: 'https://avatars.githubusercontent.com/u/28616219?v=4',
|
||||||
|
desc: 'Founder, Design Engineer',
|
||||||
|
name: 'Arvin Xu',
|
||||||
|
url: 'https://github.com/arvinxx',
|
||||||
|
},
|
||||||
|
canisminor: {
|
||||||
|
avatar: 'https://avatars.githubusercontent.com/u/17870709?v=4',
|
||||||
|
desc: 'Founder, Design Engineer',
|
||||||
|
name: 'CanisMinor',
|
||||||
|
url: 'https://github.com/arvinxx',
|
||||||
|
},
|
||||||
|
lobehub: {
|
||||||
|
avatar: 'https://avatars.githubusercontent.com/u/131470832?v=4',
|
||||||
|
desc: 'Official Account',
|
||||||
|
name: 'LobeHub',
|
||||||
|
url: 'https://github.com/lobehub',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
class Ld {
|
||||||
|
generate({
|
||||||
|
image = '/og/cover.png',
|
||||||
|
url,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
date,
|
||||||
|
webpage = {
|
||||||
|
enable: true,
|
||||||
|
},
|
||||||
|
}: {
|
||||||
|
date?: string;
|
||||||
|
description: string;
|
||||||
|
image?: string;
|
||||||
|
title: string;
|
||||||
|
url: string;
|
||||||
|
webpage?: {
|
||||||
|
enable?: boolean;
|
||||||
|
search?: boolean;
|
||||||
|
};
|
||||||
|
}) {
|
||||||
|
return {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@graph': [
|
||||||
|
this.genWebSite(),
|
||||||
|
webpage?.enable &&
|
||||||
|
this.genWebPage({
|
||||||
|
...webpage,
|
||||||
|
date,
|
||||||
|
description,
|
||||||
|
image,
|
||||||
|
title,
|
||||||
|
url,
|
||||||
|
}),
|
||||||
|
image && this.genImageObject({ image, url }),
|
||||||
|
this.genOrganization(),
|
||||||
|
].filter(Boolean),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
genOrganization() {
|
||||||
|
return {
|
||||||
|
'@id': this.getId(SITE_URL, '#organization'),
|
||||||
|
'@type': 'Organization',
|
||||||
|
'alternateName': 'LobeTheme',
|
||||||
|
'contactPoint': {
|
||||||
|
'@type': 'ContactPoint',
|
||||||
|
'contactType': 'customer support',
|
||||||
|
'email': EMAIL_SUPPORT,
|
||||||
|
},
|
||||||
|
'description':
|
||||||
|
'We are a group of e/acc design-engineers, hoping to provide modern design components and tools for AIGC, and creating a technology-driven forum, fostering knowledge interaction and the exchange of ideas that may culminate in mutual inspiration and collaborative innovation.',
|
||||||
|
'email': EMAIL_BUSINESS,
|
||||||
|
'founders': [this.getAuthors(['arvinxx']), this.getAuthors(['canisminor'])],
|
||||||
|
'image': urlJoin(OFFICIAL_SITE, '/icon-512x512.png'),
|
||||||
|
'logo': {
|
||||||
|
'@type': 'ImageObject',
|
||||||
|
'height': 512,
|
||||||
|
'url': urlJoin(OFFICIAL_SITE, '/icon-512x512.png'),
|
||||||
|
'width': 512,
|
||||||
|
},
|
||||||
|
'name': 'LobeHub',
|
||||||
|
'sameAs': [
|
||||||
|
X,
|
||||||
|
'https://github.com/lobehub',
|
||||||
|
'https://medium.com/@lobehub',
|
||||||
|
'https://www.youtube.com/@lobehub',
|
||||||
|
],
|
||||||
|
'url': OFFICIAL_SITE,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getAuthors(ids: string[] = []) {
|
||||||
|
const defaultAuthor = {
|
||||||
|
'@id': this.getId(SITE_URL, '#organization'),
|
||||||
|
'@type': 'Organization',
|
||||||
|
};
|
||||||
|
if (!ids || ids.length === 0) return defaultAuthor;
|
||||||
|
if (ids.length === 1 && ids[0] === 'lobehub') return defaultAuthor;
|
||||||
|
const personId = ids.find((id) => id !== 'lobehub');
|
||||||
|
if (!personId) return defaultAuthor;
|
||||||
|
const person = (AUTHOR_LIST as any)?.[personId];
|
||||||
|
if (!person) return defaultAuthor;
|
||||||
|
return {
|
||||||
|
'@type': 'Person',
|
||||||
|
'name': person.name,
|
||||||
|
'url': person.url,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
genWebPage({
|
||||||
|
date,
|
||||||
|
image,
|
||||||
|
search,
|
||||||
|
description,
|
||||||
|
title,
|
||||||
|
url,
|
||||||
|
}: {
|
||||||
|
breadcrumbs?: { title: string; url: string }[];
|
||||||
|
date?: string;
|
||||||
|
description: string;
|
||||||
|
image?: string;
|
||||||
|
search?: boolean;
|
||||||
|
title: string;
|
||||||
|
url: string;
|
||||||
|
}) {
|
||||||
|
const fixedUrl = this.fixUrl(url);
|
||||||
|
const dateCreated = date ? new Date(date).toISOString() : LAST_MODIFIED;
|
||||||
|
const dateModified = date ? new Date(date).toISOString() : LAST_MODIFIED;
|
||||||
|
|
||||||
|
const baseInfo: any = {
|
||||||
|
'@id': fixedUrl,
|
||||||
|
'@type': 'WebPage',
|
||||||
|
'about': {
|
||||||
|
'@id': this.getId(SITE_URL, '#organization'),
|
||||||
|
},
|
||||||
|
'breadcrumbs': {
|
||||||
|
'@id': this.getId(fixedUrl, '#breadcrumb'),
|
||||||
|
},
|
||||||
|
'dateModified': dateModified,
|
||||||
|
'datePublished': dateCreated,
|
||||||
|
'description': description,
|
||||||
|
'image': {
|
||||||
|
'@id': this.getId(fixedUrl, '#primaryimage'),
|
||||||
|
},
|
||||||
|
'inLanguage': 'en-US',
|
||||||
|
'isPartOf': {
|
||||||
|
'@id': this.getId(SITE_URL, '#website'),
|
||||||
|
},
|
||||||
|
'name': this.fixTitle(title),
|
||||||
|
'primaryImageOfPage': {
|
||||||
|
'@id': this.getId(fixedUrl, '#primaryimage'),
|
||||||
|
},
|
||||||
|
'thumbnailUrl': image,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (search) {
|
||||||
|
baseInfo.potentialAction = {
|
||||||
|
'@type': 'SearchAction',
|
||||||
|
'query-input': 'required name=search_term_string',
|
||||||
|
'target': `${fixedUrl}?q={search_term_string}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
genImageObject({ image, url }: { image: string; url: string }) {
|
||||||
|
const fixedUrl = this.fixUrl(url);
|
||||||
|
|
||||||
|
return {
|
||||||
|
'@id': this.getId(fixedUrl, '#primaryimage'),
|
||||||
|
'@type': 'ImageObject',
|
||||||
|
'contentUrl': image,
|
||||||
|
'inLanguage': 'en-US',
|
||||||
|
'url': image,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
genWebSite() {
|
||||||
|
const baseInfo: any = {
|
||||||
|
'@id': this.getId(SITE_URL, '#website'),
|
||||||
|
'@type': 'WebSite',
|
||||||
|
'description': pkg.description,
|
||||||
|
'inLanguage': 'en-US',
|
||||||
|
'name': 'LobeTheme',
|
||||||
|
'publisher': {
|
||||||
|
'@id': this.getId(SITE_URL, '#organization'),
|
||||||
|
},
|
||||||
|
'url': SITE_URL,
|
||||||
|
};
|
||||||
|
|
||||||
|
return baseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getId(url: string, id: string) {
|
||||||
|
return [url, id].join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
private fixTitle(title: string) {
|
||||||
|
return title.includes('LobeTheme') ? title : `${title} · LobeTheme`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private fixUrl(url: string) {
|
||||||
|
return urlJoin(SITE_URL, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ldModule = new Ld();
|
||||||
|
|
@ -2,10 +2,14 @@ import pkg from '@/../package.json';
|
||||||
|
|
||||||
export const DISCORD_URL = 'https://discord.gg/AYFPHvv2jT';
|
export const DISCORD_URL = 'https://discord.gg/AYFPHvv2jT';
|
||||||
export const SPONSOR_URL = 'https://opencollective.com/lobehub';
|
export const SPONSOR_URL = 'https://opencollective.com/lobehub';
|
||||||
export const SPONSOR_IMG = 'https://readme-wizard.lobehub.com/api/sponsor';
|
|
||||||
export const GISCUS_REPO_ID = 'R_kgDOJCPcNg';
|
export const GISCUS_REPO_ID = 'R_kgDOJCPcNg';
|
||||||
export const GITHUB_REPO_URL = pkg.homepage;
|
export const GITHUB_REPO_URL = pkg.homepage;
|
||||||
export const REPO_NAME = GITHUB_REPO_URL.replace(
|
export const REPO_NAME = GITHUB_REPO_URL.replace(
|
||||||
'https://github.com/',
|
'https://github.com/',
|
||||||
'',
|
'',
|
||||||
) as `${string}/${string}`;
|
) as `${string}/${string}`;
|
||||||
|
export const OFFICIAL_SITE = 'https://lobehub.com/';
|
||||||
|
export const SITE_URL = location.origin;
|
||||||
|
export const EMAIL_SUPPORT = 'support@lobehub.com';
|
||||||
|
export const EMAIL_BUSINESS = 'hello@lobehub.com';
|
||||||
|
export const X = 'https://x.com/lobehub';
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,14 @@ export const useStyles = createStyles(
|
||||||
overflow: unset;
|
overflow: unset;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(${size}px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(${size}px, 1fr));
|
||||||
|
flex: none !important;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
||||||
height: unset;
|
height: unset;
|
||||||
min-height: unset;
|
min-height: unset;
|
||||||
|
|
||||||
|
border: unset !important;
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
background: unset !important;
|
background: unset !important;
|
||||||
}
|
}
|
||||||
|
|
@ -55,6 +58,19 @@ export const useStyles = createStyles(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.extra-network-dirs {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 6px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
|
> button.lg.secondary.gradio-button {
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.extra-networks {
|
.extra-networks {
|
||||||
.pending {
|
.pending {
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
|
|
@ -78,6 +94,37 @@ export const useStyles = createStyles(
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.extra-networks-controls-div {
|
||||||
|
height: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.extra-network-control {
|
||||||
|
position: relative;
|
||||||
|
flex: none;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
.extra-network-control--search {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
> div:has(i) {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex: none;
|
||||||
|
|
||||||
|
height: 32px;
|
||||||
|
|
||||||
|
background: ${token.colorFillTertiary};
|
||||||
|
border-radius: ${token.borderRadius}px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-subdirs {
|
.extra-network-subdirs {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { Form, Swatches } from '@lobehub/ui';
|
import { Form, Swatches } from '@lobehub/ui';
|
||||||
import { Input, Segmented, Select, Switch } from 'antd';
|
import { Input, Segmented, Select, Switch } from 'antd';
|
||||||
import isEqual from 'fast-deep-equal';
|
import isEqual from 'fast-deep-equal';
|
||||||
import { Palette } from 'lucide-react';
|
|
||||||
import { memo, useCallback, useMemo, useState } from 'react';
|
import { memo, useCallback, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
|
@ -153,7 +152,7 @@ const SettingForm = memo(() => {
|
||||||
valuePropName: 'checked',
|
valuePropName: 'checked',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
icon: Palette,
|
|
||||||
title: t('setting.group.theme'),
|
title: t('setting.group.theme'),
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
|
|
@ -173,6 +172,7 @@ const SettingForm = memo(() => {
|
||||||
onFinish={onFinish}
|
onFinish={onFinish}
|
||||||
onValuesChange={(_, v) => setRawSetting(v)}
|
onValuesChange={(_, v) => setRawSetting(v)}
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
|
variant={'pure'}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { Form } from '@lobehub/ui';
|
import { Form } from '@lobehub/ui';
|
||||||
import { Switch } from 'antd';
|
import { Switch } from 'antd';
|
||||||
import isEqual from 'fast-deep-equal';
|
import isEqual from 'fast-deep-equal';
|
||||||
import { Puzzle, TextCursorInput } from 'lucide-react';
|
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
|
@ -31,7 +30,6 @@ const SettingForm = memo(() => {
|
||||||
valuePropName: 'checked',
|
valuePropName: 'checked',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
icon: Puzzle,
|
|
||||||
title: t('setting.group.experimental'),
|
title: t('setting.group.experimental'),
|
||||||
}),
|
}),
|
||||||
[],
|
[],
|
||||||
|
|
@ -55,7 +53,6 @@ const SettingForm = memo(() => {
|
||||||
valuePropName: 'checked',
|
valuePropName: 'checked',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
icon: TextCursorInput,
|
|
||||||
title: t('setting.group.promptTextarea'),
|
title: t('setting.group.promptTextarea'),
|
||||||
}),
|
}),
|
||||||
[],
|
[],
|
||||||
|
|
@ -68,6 +65,7 @@ const SettingForm = memo(() => {
|
||||||
items={[experimental, promptTextarea]}
|
items={[experimental, promptTextarea]}
|
||||||
onFinish={onFinish}
|
onFinish={onFinish}
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
|
variant={'pure'}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { Form } from '@lobehub/ui';
|
import { Form } from '@lobehub/ui';
|
||||||
import { Segmented, Switch } from 'antd';
|
import { Segmented, Switch } from 'antd';
|
||||||
import isEqual from 'fast-deep-equal';
|
import isEqual from 'fast-deep-equal';
|
||||||
import { Layout, TextCursorInput } from 'lucide-react';
|
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
|
@ -38,7 +37,7 @@ const SettingForm = memo(() => {
|
||||||
valuePropName: 'checked',
|
valuePropName: 'checked',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
icon: Layout,
|
|
||||||
title: t('setting.group.layout'),
|
title: t('setting.group.layout'),
|
||||||
}),
|
}),
|
||||||
[],
|
[],
|
||||||
|
|
@ -67,7 +66,7 @@ const SettingForm = memo(() => {
|
||||||
name: 'promptTextareaType',
|
name: 'promptTextareaType',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
icon: TextCursorInput,
|
|
||||||
title: t('setting.group.promptTextarea'),
|
title: t('setting.group.promptTextarea'),
|
||||||
}),
|
}),
|
||||||
[],
|
[],
|
||||||
|
|
@ -80,6 +79,7 @@ const SettingForm = memo(() => {
|
||||||
items={[layout, promptTextarea]}
|
items={[layout, promptTextarea]}
|
||||||
onFinish={onFinish}
|
onFinish={onFinish}
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
|
variant={'pure'}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { Form } from '@lobehub/ui';
|
import { Form } from '@lobehub/ui';
|
||||||
import { InputNumber, Segmented, Switch } from 'antd';
|
import { InputNumber, Segmented, Switch } from 'antd';
|
||||||
import isEqual from 'fast-deep-equal';
|
import isEqual from 'fast-deep-equal';
|
||||||
import { PanelLeftClose, PanelRightClose } from 'lucide-react';
|
|
||||||
import { memo, useCallback, useMemo, useState } from 'react';
|
import { memo, useCallback, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
|
@ -67,7 +66,7 @@ const SettingForm = memo(() => {
|
||||||
name: 'sidebarWidth',
|
name: 'sidebarWidth',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
icon: PanelLeftClose,
|
|
||||||
title: t('setting.group.quickSettingSidebar'),
|
title: t('setting.group.quickSettingSidebar'),
|
||||||
}),
|
}),
|
||||||
[rawSetting.enableSidebar],
|
[rawSetting.enableSidebar],
|
||||||
|
|
@ -126,7 +125,7 @@ const SettingForm = memo(() => {
|
||||||
name: 'extraNetworkCardSize',
|
name: 'extraNetworkCardSize',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
icon: PanelRightClose,
|
|
||||||
title: t('setting.group.extraNetworkSidebar'),
|
title: t('setting.group.extraNetworkSidebar'),
|
||||||
}),
|
}),
|
||||||
[rawSetting.enableExtraNetworkSidebar],
|
[rawSetting.enableExtraNetworkSidebar],
|
||||||
|
|
@ -140,6 +139,7 @@ const SettingForm = memo(() => {
|
||||||
onFinish={onFinish}
|
onFinish={onFinish}
|
||||||
onValuesChange={(_, v) => setRawSetting(v)}
|
onValuesChange={(_, v) => setRawSetting(v)}
|
||||||
style={{ flex: 1 }}
|
style={{ flex: 1 }}
|
||||||
|
variant={'pure'}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { Logo } from '@lobehub/ui';
|
||||||
|
import { createStyles } from 'antd-style';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { Flexbox, FlexboxProps } from 'react-layout-kit';
|
||||||
|
|
||||||
|
const useStyles = createStyles(({ token, css }) => ({
|
||||||
|
logoLink: css`
|
||||||
|
height: 20px;
|
||||||
|
color: inherit;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: ${token.colorLink};
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const BrandWatermark = memo<Omit<FlexboxProps, 'children'>>(({ style, ...rest }) => {
|
||||||
|
const { styles, theme } = useStyles();
|
||||||
|
return (
|
||||||
|
<Flexbox
|
||||||
|
align={'center'}
|
||||||
|
flex={'none'}
|
||||||
|
gap={4}
|
||||||
|
horizontal
|
||||||
|
style={{ color: theme.colorTextDescription, fontSize: 12, ...style }}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
<span>Powered by</span>
|
||||||
|
<a
|
||||||
|
className={styles.logoLink}
|
||||||
|
href={'https://lobehub.com'}
|
||||||
|
rel="noreferrer"
|
||||||
|
target={'_blank'}
|
||||||
|
>
|
||||||
|
<Logo size={20} type={'text'} />
|
||||||
|
</a>
|
||||||
|
</Flexbox>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BrandWatermark;
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
import { Icon, List } from '@lobehub/ui';
|
|
||||||
import { createStyles } from 'antd-style';
|
|
||||||
import { type LucideIcon } from 'lucide-react';
|
|
||||||
import { CSSProperties, ReactNode, memo } from 'react';
|
|
||||||
|
|
||||||
const { Item } = List;
|
|
||||||
|
|
||||||
const useStyles = createStyles(({ css, token }) => ({
|
|
||||||
container: css`
|
|
||||||
position: relative;
|
|
||||||
padding: 16px;
|
|
||||||
border-radius: ${token.borderRadius}px;
|
|
||||||
|
|
||||||
div {
|
|
||||||
overflow: visible;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
}));
|
|
||||||
|
|
||||||
export interface ItemProps {
|
|
||||||
active?: boolean;
|
|
||||||
className?: string;
|
|
||||||
icon: LucideIcon;
|
|
||||||
label: ReactNode;
|
|
||||||
onClick?: () => void;
|
|
||||||
style?: CSSProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SettingItem = memo<ItemProps>(
|
|
||||||
({ label, icon, active = false, style, className, onClick }) => {
|
|
||||||
const { cx, styles } = useStyles();
|
|
||||||
return (
|
|
||||||
<Item
|
|
||||||
active={active}
|
|
||||||
avatar={<Icon icon={icon} size={{ fontSize: 16 }} />}
|
|
||||||
className={cx(styles.container, className)}
|
|
||||||
onClick={onClick}
|
|
||||||
style={style}
|
|
||||||
title={label as string}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export default SettingItem;
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
import { Menu as AntdMenu, MenuProps as AntdMenuProps, ConfigProvider } from 'antd';
|
||||||
|
import { createStyles } from 'antd-style';
|
||||||
|
import { memo } from 'react';
|
||||||
|
|
||||||
|
const useStyles = createStyles(({ css, token, prefixCls }) => ({
|
||||||
|
compact: css`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.125rem;
|
||||||
|
`,
|
||||||
|
menu: css`
|
||||||
|
flex: 1;
|
||||||
|
background: transparent;
|
||||||
|
border: none !important;
|
||||||
|
|
||||||
|
.${prefixCls}-menu-item-divider {
|
||||||
|
margin-block: 0.125rem;
|
||||||
|
border-color: ${token.colorFillTertiary};
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.${prefixCls}-menu-item, .${prefixCls}-menu-submenu-title {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.75rem;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
height: unset;
|
||||||
|
min-height: 2rem;
|
||||||
|
padding: 0.375rem 0.75rem;
|
||||||
|
|
||||||
|
line-height: 2;
|
||||||
|
|
||||||
|
.anticon + .${prefixCls}-menu-title-content {
|
||||||
|
margin-inline-start: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.${prefixCls}-menu-item-selected {
|
||||||
|
.${prefixCls}-menu-item-icon svg {
|
||||||
|
color: ${token.colorText};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.${prefixCls}-menu-item-icon svg {
|
||||||
|
color: ${token.colorTextSecondary};
|
||||||
|
}
|
||||||
|
|
||||||
|
.${prefixCls}-menu-title-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export interface MenuProps extends AntdMenuProps {
|
||||||
|
variant?: 'default' | 'compact';
|
||||||
|
}
|
||||||
|
|
||||||
|
const Menu = memo<MenuProps>(({ className, selectable = false, variant, ...rest }) => {
|
||||||
|
const isCompact = variant === 'compact';
|
||||||
|
const { cx, styles, theme } = useStyles();
|
||||||
|
return (
|
||||||
|
<ConfigProvider
|
||||||
|
theme={{
|
||||||
|
components: {
|
||||||
|
Menu: {
|
||||||
|
controlHeightLG: 36,
|
||||||
|
iconMarginInlineEnd: 8,
|
||||||
|
iconSize: 16,
|
||||||
|
itemBorderRadius: theme.borderRadius,
|
||||||
|
itemColor: selectable ? theme.colorTextSecondary : theme.colorText,
|
||||||
|
itemHoverBg: theme.colorFillTertiary,
|
||||||
|
itemMarginBlock: isCompact ? 0 : 4,
|
||||||
|
itemMarginInline: isCompact ? 0 : 4,
|
||||||
|
itemSelectedBg: theme.colorFillSecondary,
|
||||||
|
paddingXS: -8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AntdMenu
|
||||||
|
className={cx(styles.menu, isCompact && styles.compact, className)}
|
||||||
|
mode="vertical"
|
||||||
|
selectable={selectable}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
</ConfigProvider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Menu;
|
||||||
|
|
@ -15,7 +15,7 @@ const MobileSidebar = memo<SidebarProps>(({ tab, setTab }) => {
|
||||||
<Segmented
|
<Segmented
|
||||||
block
|
block
|
||||||
onChange={setTab as any}
|
onChange={setTab as any}
|
||||||
options={items.map(({ value, label }) => ({ label, value }))}
|
options={items.map(({ key, label }) => ({ label, value: key }))}
|
||||||
value={tab}
|
value={tab}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { createStyles } from 'antd-style';
|
||||||
|
import { ReactNode } from 'react';
|
||||||
|
import { Flexbox, FlexboxProps } from 'react-layout-kit';
|
||||||
|
|
||||||
|
import BrandWatermark from './BrandWatermark';
|
||||||
|
|
||||||
|
const useStyles = createStyles(({ token, css }) => ({
|
||||||
|
container: css`
|
||||||
|
padding: 24px 12px 16px;
|
||||||
|
background: ${token.colorBgContainer};
|
||||||
|
border-inline-end: 1px solid ${token.colorBorder};
|
||||||
|
`,
|
||||||
|
desc: css`
|
||||||
|
line-height: 1.4;
|
||||||
|
color: ${token.colorTextDescription};
|
||||||
|
`,
|
||||||
|
header: css`
|
||||||
|
padding: 0 0.75rem;
|
||||||
|
`,
|
||||||
|
logo: css`
|
||||||
|
fill: ${token.colorText};
|
||||||
|
`,
|
||||||
|
title: css`
|
||||||
|
margin: 0;
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.3;
|
||||||
|
`,
|
||||||
|
}));
|
||||||
|
|
||||||
|
interface SidebarLayoutProps extends FlexboxProps {
|
||||||
|
desc?: ReactNode;
|
||||||
|
title?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SidebarLayout = ({ children, className, title, desc, ...rest }: SidebarLayoutProps) => {
|
||||||
|
const { cx, styles } = useStyles();
|
||||||
|
return (
|
||||||
|
<Flexbox
|
||||||
|
className={cx(styles.container, className)}
|
||||||
|
flex={'none'}
|
||||||
|
gap={20}
|
||||||
|
width={280}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
<Flexbox className={styles.header} gap={4}>
|
||||||
|
<h1 className={styles.title}>{title}</h1>
|
||||||
|
{desc && <p className={styles.desc}>{desc}</p>}
|
||||||
|
</Flexbox>
|
||||||
|
{children}
|
||||||
|
<BrandWatermark paddingInline={12} />
|
||||||
|
</Flexbox>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SidebarLayout;
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Flexbox } from 'react-layout-kit';
|
import { Flexbox } from 'react-layout-kit';
|
||||||
|
|
||||||
import { useTabItems } from '@/features/Setting/Sidebar/useTabItems';
|
import VersionTag from '../../../components/VersionTag';
|
||||||
|
import Menu from './Menu';
|
||||||
import Item from './Item';
|
import SidebarLayout from './SidebarLayout';
|
||||||
|
import { useTabItems } from './useTabItems';
|
||||||
|
|
||||||
export enum SettingsTabs {
|
export enum SettingsTabs {
|
||||||
Appearance = 'appearance',
|
Appearance = 'appearance',
|
||||||
|
|
@ -19,19 +21,24 @@ interface SidebarProps {
|
||||||
|
|
||||||
const Sidebar = memo<SidebarProps>(({ tab, setTab }) => {
|
const Sidebar = memo<SidebarProps>(({ tab, setTab }) => {
|
||||||
const items = useTabItems();
|
const items = useTabItems();
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Flexbox gap={4}>
|
<SidebarLayout
|
||||||
{items.map(({ value, icon, label }) => (
|
desc={
|
||||||
<Item
|
<Flexbox align={'center'} gap={4} horizontal>
|
||||||
active={tab === value}
|
{t('modal.themeSetting.desc')}
|
||||||
icon={icon}
|
<VersionTag />
|
||||||
key={value}
|
</Flexbox>
|
||||||
label={label}
|
}
|
||||||
onClick={() => setTab(value)}
|
title={t('modal.themeSetting.title')}
|
||||||
/>
|
>
|
||||||
))}
|
<Menu
|
||||||
</Flexbox>
|
items={items}
|
||||||
|
onClick={({ key }) => setTab(key as SettingsTabs)}
|
||||||
|
selectable
|
||||||
|
selectedKeys={[tab as any]}
|
||||||
|
/>
|
||||||
|
</SidebarLayout>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import { Brush, FlaskConical, Layout, PanelRight } from 'lucide-react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
import { SettingsTabs } from '@/features/Setting/Sidebar/index';
|
|
||||||
|
|
||||||
export const useTabItems = () => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return [
|
|
||||||
{ icon: Brush, label: t('setting.tab.appearance'), value: SettingsTabs.Appearance },
|
|
||||||
{ icon: Layout, label: t('setting.tab.layout'), value: SettingsTabs.Layout },
|
|
||||||
{ icon: PanelRight, label: t('setting.tab.sidebar'), value: SettingsTabs.Sidebar },
|
|
||||||
{ icon: FlaskConical, label: t('setting.tab.experimental'), value: SettingsTabs.Experimental },
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Icon } from '@lobehub/ui';
|
||||||
|
import { Brush, FlaskConical, Layout, PanelRight } from 'lucide-react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { SettingsTabs } from '@/features/Setting/Sidebar/index';
|
||||||
|
|
||||||
|
export const useTabItems = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
icon: <Icon icon={Brush} />,
|
||||||
|
key: SettingsTabs.Appearance,
|
||||||
|
label: t('setting.tab.appearance'),
|
||||||
|
},
|
||||||
|
{ icon: <Icon icon={Layout} />, key: SettingsTabs.Layout, label: t('setting.tab.layout') },
|
||||||
|
{
|
||||||
|
icon: <Icon icon={PanelRight} />,
|
||||||
|
key: SettingsTabs.Sidebar,
|
||||||
|
label: t('setting.tab.sidebar'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <Icon icon={FlaskConical} />,
|
||||||
|
key: SettingsTabs.Experimental,
|
||||||
|
label: t('setting.tab.experimental'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
@ -1,13 +1,8 @@
|
||||||
import { ActionIcon, Modal, type ModalProps } from '@lobehub/ui';
|
import { Modal, type ModalProps } from '@lobehub/ui';
|
||||||
import { useResponsive } from 'antd-style';
|
import { useResponsive, useTheme } from 'antd-style';
|
||||||
import { Book } from 'lucide-react';
|
|
||||||
import { memo, useState } from 'react';
|
import { memo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { Flexbox } from 'react-layout-kit';
|
import { Flexbox } from 'react-layout-kit';
|
||||||
|
|
||||||
import VersionTag from '@/components/VersionTag';
|
|
||||||
import { GITHUB_REPO_URL } from '@/const/url';
|
|
||||||
|
|
||||||
import FormAppearance from './Form/Appearance';
|
import FormAppearance from './Form/Appearance';
|
||||||
import FormExperimental from './Form/Experimental';
|
import FormExperimental from './Form/Experimental';
|
||||||
import Footer from './Form/Footer';
|
import Footer from './Form/Footer';
|
||||||
|
|
@ -23,7 +18,7 @@ export interface SettingProps {
|
||||||
const Setting = memo<SettingProps>(({ open, onCancel }) => {
|
const Setting = memo<SettingProps>(({ open, onCancel }) => {
|
||||||
const [tab, setTab] = useState<SettingsTabs>(SettingsTabs.Appearance);
|
const [tab, setTab] = useState<SettingsTabs>(SettingsTabs.Appearance);
|
||||||
const { mobile } = useResponsive();
|
const { mobile } = useResponsive();
|
||||||
const { t } = useTranslation();
|
const theme = useTheme();
|
||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
<>
|
<>
|
||||||
|
|
@ -36,37 +31,65 @@ const Setting = memo<SettingProps>(({ open, onCancel }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
footer={<Footer />}
|
allowFullscreen={true}
|
||||||
|
footer={mobile ? <Footer /> : null}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
open={open}
|
open={open}
|
||||||
styles={{
|
styles={{
|
||||||
body: mobile ? { padding: 0 } : {},
|
body: {
|
||||||
|
display: 'flex',
|
||||||
|
minHeight: 'min(75vh, 750px)',
|
||||||
|
overflow: 'hidden',
|
||||||
|
padding: 0,
|
||||||
|
paddingBlock: 0,
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
background: mobile ? theme.colorBgContainer : undefined,
|
||||||
|
border: 'none',
|
||||||
|
boxShadow: `0 0 0 1px ${theme.colorBorderSecondary}`,
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
title={
|
title={false}
|
||||||
<Flexbox align={'center'} gap={4}>
|
width={1024}
|
||||||
<Flexbox align={'center'} gap={4} horizontal>
|
|
||||||
<a href={GITHUB_REPO_URL} rel="noreferrer" target="_blank">
|
|
||||||
<ActionIcon icon={Book} title="Setting Documents" />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{t('modal.themeSetting.title')}
|
|
||||||
<VersionTag />
|
|
||||||
</Flexbox>
|
|
||||||
</Flexbox>
|
|
||||||
}
|
|
||||||
width={960}
|
|
||||||
>
|
>
|
||||||
{mobile ? (
|
{mobile ? (
|
||||||
<Flexbox>
|
<Flexbox
|
||||||
|
height={'100%'}
|
||||||
|
style={{ overflow: 'hidden', position: 'relative' }}
|
||||||
|
width={'100%'}
|
||||||
|
>
|
||||||
<div style={{ padding: 16 }}>
|
<div style={{ padding: 16 }}>
|
||||||
<MobileSidebar setTab={setTab} tab={tab} />
|
<MobileSidebar setTab={setTab} tab={tab} />
|
||||||
</div>
|
</div>
|
||||||
{content}
|
<Flexbox
|
||||||
|
height={'100%'}
|
||||||
|
style={{ overflowX: 'hidden', overflowY: 'auto', position: 'relative' }}
|
||||||
|
width={'100%'}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</Flexbox>
|
||||||
</Flexbox>
|
</Flexbox>
|
||||||
) : (
|
) : (
|
||||||
<Flexbox gap={16} horizontal>
|
<Flexbox horizontal width={'100%'}>
|
||||||
<Sidebar setTab={setTab} tab={tab} />
|
<Sidebar setTab={setTab} tab={tab} />
|
||||||
{content}
|
<Flexbox
|
||||||
|
align={'center'}
|
||||||
|
gap={64}
|
||||||
|
style={{
|
||||||
|
background: theme.isDarkMode ? theme.colorFillQuaternary : theme.colorBgElevated,
|
||||||
|
minHeight: '100%',
|
||||||
|
overflowX: 'hidden',
|
||||||
|
overflowY: 'auto',
|
||||||
|
paddingBlock: 40,
|
||||||
|
paddingInline: 56,
|
||||||
|
}}
|
||||||
|
width={'100%'}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
<Flexbox width={'100%'}>
|
||||||
|
<Footer />
|
||||||
|
</Flexbox>
|
||||||
|
</Flexbox>
|
||||||
</Flexbox>
|
</Flexbox>
|
||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { Converter } from '@/scripts/formatPrompt';
|
|
||||||
import { parseFromRawInfo } from '@bluelovers/auto1111-pnginfo';
|
import { parseFromRawInfo } from '@bluelovers/auto1111-pnginfo';
|
||||||
|
|
||||||
|
import { Converter } from '@/scripts/formatPrompt';
|
||||||
|
|
||||||
const formatPrompt = (prompt: string) => {
|
const formatPrompt = (prompt: string) => {
|
||||||
let newPrompt = prompt.replaceAll('<', '<').replaceAll('>', '>');
|
let newPrompt = prompt.replaceAll('<', '<').replaceAll('>', '>');
|
||||||
return Converter.convert(newPrompt);
|
return Converter.convert(newPrompt);
|
||||||
|
|
@ -13,13 +14,13 @@ export const formatInfo = (info: string) => {
|
||||||
let {
|
let {
|
||||||
prompt: position,
|
prompt: position,
|
||||||
negative_prompt: negative,
|
negative_prompt: negative,
|
||||||
...config,
|
...config
|
||||||
} = parseFromRawInfo(info, {
|
} = parseFromRawInfo(info, {
|
||||||
isIncludePrompts: true,
|
isIncludePrompts: true,
|
||||||
})
|
});
|
||||||
|
|
||||||
position = position.trim().replaceAll('<br>', '\n').replace(/[\s\r\n]+$/g, '');
|
position = position.trim().replaceAll('<br>', '\n').replaceAll(/\s+$/g, '');
|
||||||
negative = negative.trim().replaceAll('<br>', '\n').replace(/[\s\r\n]+$/g, '');
|
negative = negative.trim().replaceAll('<br>', '\n').replaceAll(/\s+$/g, '');
|
||||||
|
|
||||||
position = position ? formatPrompt(position) : '';
|
position = position ? formatPrompt(position) : '';
|
||||||
negative = negative ? formatPrompt(negative) : '';
|
negative = negative ? formatPrompt(negative) : '';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue