🐛 fix(split-view): Fix split view

This commit is contained in:
canisminor1990 2023-09-04 16:42:27 +08:00
parent c320ec2982
commit f1d5ab205e
13 changed files with 113 additions and 391 deletions

View File

@ -47,6 +47,12 @@ jobs:
- name: Install deps
run: pnpm install
- name: Build
run: pnpm run build
- name: Git add
run: git add -f javascript/main.js
- name: Release
id: release
run: pnpm run release

1
.gitignore vendored
View File

@ -43,4 +43,3 @@ test-output
__pycache__
/lobe_theme_config.json
/javascript/*.js
!/javascript/main.js

View File

@ -55,6 +55,7 @@ Dockerfile*
# misc
# add other ignore file below
*.py
style.css
javascript/
.stylelintignore

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,34 @@
import { memo, useEffect } from 'react';
const Preview = memo(() => {
useEffect(() => {
console.time('🤯 [layout] inject - Split Previewer');
// tab_txt2img
const txt2imgToprow = gradioApp().querySelector('#txt2img_toprow') as HTMLDivElement;
const txt2imgSettings = gradioApp().querySelector('#txt2img_settings') as HTMLDivElement;
const txt2imgGenerate = gradioApp().querySelector('#txt2img_generate') as HTMLButtonElement;
const txt2imgPreview = gradioApp().querySelector(
'#txt2img_gallery_container',
) as HTMLDivElement;
if (txt2imgToprow && txt2imgSettings && txt2imgGenerate && txt2imgPreview) {
txt2imgSettings.prepend(txt2imgToprow);
txt2imgPreview.prepend(txt2imgGenerate);
}
// tab_img2img
const img2imgToprow = gradioApp().querySelector('#img2img_toprow') as HTMLDivElement;
const img2imgSettings = gradioApp().querySelector('#img2img_settings') as HTMLDivElement;
const img2imgGenerate = gradioApp().querySelector('#img2img_generate') as HTMLButtonElement;
const img2imgPreview = gradioApp().querySelector(
'#img2img_gallery_container',
) as HTMLDivElement;
if (img2imgSettings && img2imgToprow && img2imgGenerate && img2imgPreview) {
img2imgSettings.prepend(img2imgToprow);
img2imgPreview.prepend(img2imgGenerate);
}
console.timeEnd('🤯 [layout] inject - Split Previewer');
}, []);
return null;
});
export default Preview;

View File

@ -1,3 +1,4 @@
import { useResponsive } from 'antd-style';
import isEqual from 'fast-deep-equal';
import { memo, useEffect, useRef } from 'react';
@ -5,10 +6,12 @@ import formatPrompt from '@/script/formatPrompt';
import { selectors, useAppStore } from '@/store';
import { type DivProps } from '@/types';
import SplitView from './SplitView';
import { useStyles } from './style';
const Content = memo<DivProps>(({ className, ...props }) => {
const mainReference = useRef<HTMLDivElement>(null);
const { mobile } = useResponsive();
const setting = useAppStore(selectors.currentSetting, isEqual);
const { cx, styles } = useStyles({
@ -49,17 +52,20 @@ const Content = memo<DivProps>(({ className, ...props }) => {
}, []);
return (
<div
className={cx(
styles.container,
styles.textares,
styles.text2img,
setting.layoutSplitPreview && styles.splitView,
className,
)}
ref={mainReference}
{...props}
/>
<>
<div
className={cx(
styles.container,
styles.textares,
styles.text2img,
setting.layoutSplitPreview && styles.splitView,
className,
)}
ref={mainReference}
{...props}
/>
{setting.layoutSplitPreview && mobile === false && <SplitView />}
</>
);
});

View File

@ -27,6 +27,12 @@ export const useStyles = createStyles(
border-bottom-left-radius: 0;
}
#txt2img_results,
#img2img_results {
padding: 0 !important;
background: transparent !important;
}
#txt2img_render,
#img2img_render {
display: block !important;
@ -62,28 +68,15 @@ export const useStyles = createStyles(
}
`,
splitView: css`
#txt2img_generate,
#img2img_generate {
border-radius: ${token.borderRadius}px !important;
}
#txt2img_toprow,
#img2img_toprow {
flex-direction: column;
padding: 0 !important;
background: transparent !important;
.interrogate-col {
flex-direction: row;
max-width: 100%;
}
#txt2img_actions_column,
#img2img_actions_column {
gap: 12px;
}
#txt2img_styles_row,
#img2img_styles_row {
padding: 16px;
background: ${token.colorBgContainer};
border-radius: ${token.borderRadius}px;
}
}
`,
text2img: css`
@ -155,6 +148,7 @@ export const useStyles = createStyles(
padding: 16px !important;
background-color: ${token.colorBgContainer}!important;
border: 1px solid ${token.colorBorderSecondary} !important;
border-radius: ${token.borderRadius}px !important;
}
}

View File

@ -1,95 +0,0 @@
import { DraggablePanel, LayoutSidebarInner } from '@lobehub/ui';
import isEqual from 'fast-deep-equal';
import { memo, useEffect, useRef } from 'react';
import { shallow } from 'zustand/shallow';
import { selectors, useAppStore } from '@/store';
import { type DivProps } from '@/types';
import { useStyles } from './style';
export interface PreviewProps extends DivProps {
headerHeight: number;
}
const Preview = memo<PreviewProps>(({ headerHeight }) => {
const currentTab = useAppStore(selectors.currentTab, shallow);
const setting = useAppStore(selectors.currentSetting, isEqual);
const { cx, styles } = useStyles({
headerHeight,
isPrimaryColor: Boolean(setting.primaryColor),
liteAnimation: setting.liteAnimation,
});
const txt2imgReference = useRef<HTMLDivElement>(null);
const img2imgReference = useRef<HTMLDivElement>(null);
const extras2imgReference = useRef<HTMLDivElement>(null);
useEffect(() => {
console.time('🤯 [layout] inject - Split Previewer');
// tab_txt2img
const txt2imgToprow = gradioApp().querySelector('#txt2img_toprow') as HTMLDivElement;
const txt2imgSettings = gradioApp().querySelector('#txt2img_settings') as HTMLDivElement;
if (txt2imgToprow && txt2imgSettings) {
txt2imgSettings.prepend(txt2imgToprow);
}
// tab_img2img
const img2imgToprow = gradioApp().querySelector('#img2img_toprow') as HTMLDivElement;
const img2imgSettings = gradioApp().querySelector('#img2img_settings') as HTMLDivElement;
if (img2imgSettings && img2imgToprow) {
img2imgSettings.prepend(img2imgToprow);
}
// tab_txt2img
const txt2imgPreview = gradioApp().querySelector('#txt2img_results') as HTMLDivElement;
const txt2imgButton = gradioApp().querySelector('#txt2img_generate_box') as HTMLDivElement;
if (txt2imgPreview && txt2imgButton) {
txt2imgReference.current?.append(txt2imgButton, txt2imgPreview);
}
// tab_img2img
const img2imgPreview = gradioApp().querySelector('#img2img_results') as HTMLDivElement;
const img2imgButton = gradioApp().querySelector('#img2img_generate_box') as HTMLDivElement;
if (img2imgPreview && img2imgButton) {
img2imgReference.current?.append(img2imgButton, img2imgPreview);
}
// tab_extras
const extrasPreview = gradioApp().querySelector('#extras_results') as HTMLDivElement;
const extrasButton = gradioApp().querySelector('#extras_generate') as HTMLDivElement;
if (extrasPreview && extrasButton) {
extras2imgReference.current?.append(extrasButton, extrasPreview);
}
console.timeEnd('🤯 [layout] inject - Split Previewer');
}, []);
return (
<DraggablePanel
defaultSize={{ width: '30vw' }}
expandable={false}
minWidth={200}
mode="fixed"
pin
placement="right"
>
<LayoutSidebarInner>
<div className={styles.container}>
<div
className={cx(styles.inner, styles.preview)}
ref={txt2imgReference}
style={{ display: currentTab === 'tab_txt2img' ? 'flex' : 'none' }}
/>
<div
className={cx(styles.inner, styles.preview)}
ref={img2imgReference}
style={{ display: currentTab === 'tab_img2img' ? 'flex' : 'none' }}
/>
<div
className={cx(styles.inner, styles.preview)}
ref={extras2imgReference}
style={{ display: currentTab === 'tab_extras' ? 'flex' : 'none' }}
/>
</div>
</LayoutSidebarInner>
</DraggablePanel>
);
});
export default Preview;

View File

@ -1,113 +0,0 @@
import { createStyles } from 'antd-style';
import { adjustHue, rgba } from 'polished';
export const useStyles = createStyles(
(
{ css, token, stylish },
{
headerHeight = 64,
isPrimaryColor,
liteAnimation,
}: { headerHeight?: number; isPrimaryColor?: boolean; liteAnimation?: boolean },
) => {
const primaryGradient =
isPrimaryColor &&
css`
background-image: linear-gradient(
-45deg,
${token.colorPrimary},
${adjustHue(45, token.colorPrimary)},
${token.colorPrimary},
${adjustHue(-45, token.colorPrimary)}
);
`;
return {
container: css`
height: calc(100vh - ${headerHeight}px);
`,
inner: css`
display: flex;
flex-direction: column;
gap: 16px;
height: 100%;
padding: 16px;
[id$='_results'] {
flex: 1;
> div:not([id$='_gallery_container']) {
flex-grow: 0 !important;
}
[id$='_gallery_container'] {
flex-grow: 1 !important;
}
}
`,
preview: css`
button {
&#extras_generate {
position: relative;
}
&.svelte-1p4r00v {
padding: 0;
}
}
.progressDiv > .progress {
${!liteAnimation && stylish.gradientAnimation};
${!liteAnimation && primaryGradient};
}
[id$='_results'] {
padding: 0 !important;
background: none !important;
[id$='img_gallery_container'] {
div:not(.livePreview) {
box-sizing: border-box;
}
}
[id$='_gallery'] {
height: 100%;
}
.livePreview {
top: 28px;
left: 4px;
background: ${token.colorBgElevated};
}
.preview {
max-height: unset !important;
background: ${rgba(token.colorBgLayout, 0.5)} !important;
}
.empty {
height: 100%;
}
[id^='html_info_']:has(p) {
padding: 8px 12px;
font-family: ${token.fontFamilyCode};
font-size: 12px;
color: ${token.colorInfoText};
background: ${token.colorInfoBg};
border: 1px solid ${token.colorInfoBorder};
border-radius: ${token.borderRadius}px;
}
p {
margin: 0.2em 0;
text-align: unset;
}
}
`,
};
},
);

View File

@ -1,8 +1,6 @@
import { LayoutHeader, LayoutMain, LayoutSidebar } from '@lobehub/ui';
import { useResponsive } from 'antd-style';
import isEqual from 'fast-deep-equal';
import { memo, useEffect } from 'react';
import { shallow } from 'zustand/shallow';
import '@/i18n/config';
import { PromptHighlight } from '@/modules/PromptHighlight';
@ -14,16 +12,13 @@ import Content from './Content';
import ExtraNetworkSidebar from './ExtraNetworkSidebar';
import Footer from './Footer';
import Header from './Header';
import Preview from './Preview';
import QuickSettingSidebar from './QuickSettingSidebar';
import { useStyles } from './style';
const HEADER_HEIGHT = 64;
const Index = memo(() => {
const currentTab = useAppStore(selectors.currentTab, shallow);
const setting = useAppStore(selectors.currentSetting, isEqual);
const { mobile } = useResponsive();
const { cx, styles } = useStyles({
headerHeight: HEADER_HEIGHT,
isPrimaryColor: Boolean(setting.primaryColor),
@ -55,20 +50,6 @@ const Index = memo(() => {
</LayoutSidebar>
)}
<Content className={cx(!setting.enableSidebar && styles.quicksettings)} />
{setting.layoutSplitPreview && mobile === false && (
<LayoutSidebar
className={cx(styles.sidebar, styles.panel)}
headerHeight={HEADER_HEIGHT}
style={{
display: ['tab_txt2img', 'tab_img2img', 'tab_extras'].includes(currentTab) ?
'block' :
'none',
flex: 0,
}}
>
<Preview headerHeight={HEADER_HEIGHT} />
</LayoutSidebar>
)}
{setting?.enableExtraNetworkSidebar && (
<LayoutSidebar
className={styles.sidebar}

View File

@ -91,19 +91,19 @@ const updateCardForCivitai = () => {
metadataButton = card.querySelector('.metadata-button');
// Additional node
additionalNode = card.querySelector('.actions .additional');
// Get ul node, which is the parent of all buttons
ulNode = card.querySelector('.actions .additional ul');
if (ulNode == null) {
ulNode = document.createElement("ul");
additionalNode.appendChild(ulNode);
if (ulNode === undefined) {
ulNode = document.createElement('ul');
additionalNode.append(ulNode);
}
// Replace preview text button
replacePreviewButton = card.querySelector('.actions .additional a');
if (replacePreviewButton == null) {
replacePreviewButton = document.createElement("a");
additionalNode.appendChild(replacePreviewButton);
if (replacePreviewButton === undefined) {
replacePreviewButton = document.createElement('a');
additionalNode.append(replacePreviewButton);
}
// Check thumb mode

View File

@ -7,7 +7,11 @@ export default (token: Theme) => {
linear-gradient(-45deg, ${token.colorFillTertiary} 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, ${token.colorFillTertiary} 75%),
linear-gradient(-45deg, transparent 75%, ${token.colorFillTertiary} 75%);
background-position: 0 0, 0 10px, 10px -10px, -10px 0;
background-position:
0 0,
0 10px,
10px -10px,
-10px 0;
background-size: 20px 20px;
border: 2px solid ${token.colorBorderSecondary} !important;
border-radius: ${token.borderRadius}px !important;

View File

@ -91,8 +91,7 @@ export default (token: Theme) => {
--block-label-border-color: ${token.colorBorderSecondary};
--block-label-border-width: 1px;
--block-label-shadow: ${token.boxShadowTertiary};
--block-label-text-color: ${token.colorText}
--block-label-margin: 0;
--block-label-text-color: ${token.colorText} --block-label-margin: 0;
--block-label-padding: var(--spacing-sm) var(--spacing-lg);
--block-label-radius: ${token.borderRadius}px;
--block-label-right-radius: ${token.borderRadius}px;
@ -128,7 +127,7 @@ export default (token: Theme) => {
--checkbox-border-color-selected: ${token.colorPrimary};
--checkbox-border-radius: ${token.borderRadiusXS}px;
--checkbox-border-width: 1px;
--checkbox-label-background-fill: ${token.colorFillTertiary};
--checkbox-label-background-fill: ${token.colorFillTertiary};
--checkbox-label-background-fill-hover: ${token.colorFillSecondary};
--checkbox-label-background-fill-selected: ${token.colorFillSecondary};
--checkbox-label-border-color: ${token.colorBorderSecondary};
@ -189,7 +188,7 @@ export default (token: Theme) => {
--button-primary-text-color: ${readableColor(token.colorPrimary)};
--button-primary-text-color-hover: ${readableColor(token.colorPrimary)};
--button-secondary-background-fill: ${token.colorFillSecondary};
--button-secondary-background-fill-hover: ${token.colorFill};;
--button-secondary-background-fill-hover: ${token.colorFill};
--button-secondary-border-color: ${token.colorBorderSecondary};
--button-secondary-border-color-hover: ${token.colorBorder};
--button-secondary-text-color: ${token.colorTextSecondary};