mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Refactors gallery resizing, persists width
This commit is contained in:
parent
9fc6ee0c4c
commit
f22f81b4ff
@ -59,6 +59,7 @@ const galleryPersistConfig = {
|
|||||||
key: 'gallery',
|
key: 'gallery',
|
||||||
storage,
|
storage,
|
||||||
whitelist: [
|
whitelist: [
|
||||||
|
'galleryWidth',
|
||||||
'shouldPinGallery',
|
'shouldPinGallery',
|
||||||
'shouldShowGallery',
|
'shouldShowGallery',
|
||||||
'galleryScrollPosition',
|
'galleryScrollPosition',
|
||||||
|
@ -52,9 +52,15 @@
|
|||||||
|
|
||||||
.image-gallery-header {
|
.image-gallery-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: end;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
column-gap: 0.5rem;
|
column-gap: 0.5rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
column-gap: 0.5rem;
|
||||||
|
column-gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.image-gallery-icon-btn {
|
.image-gallery-icon-btn {
|
||||||
background-color: var(--btn-load-more) !important;
|
background-color: var(--btn-load-more) !important;
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
setGalleryImageMinimumWidth,
|
setGalleryImageMinimumWidth,
|
||||||
setGalleryImageObjectFit,
|
setGalleryImageObjectFit,
|
||||||
setGalleryScrollPosition,
|
setGalleryScrollPosition,
|
||||||
|
setGalleryWidth,
|
||||||
setShouldAutoSwitchToNewImages,
|
setShouldAutoSwitchToNewImages,
|
||||||
setShouldHoldGalleryOpen,
|
setShouldHoldGalleryOpen,
|
||||||
setShouldPinGallery,
|
setShouldPinGallery,
|
||||||
@ -33,6 +34,8 @@ import IAICheckbox from '../../common/components/IAICheckbox';
|
|||||||
import { setNeedsCache } from '../tabs/Inpainting/inpaintingSlice';
|
import { setNeedsCache } from '../tabs/Inpainting/inpaintingSlice';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
const GALLERY_SHOW_BUTTONS_MIN_WIDTH = 320;
|
||||||
|
|
||||||
export default function ImageGallery() {
|
export default function ImageGallery() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
@ -51,71 +54,39 @@ export default function ImageGallery() {
|
|||||||
shouldHoldGalleryOpen,
|
shouldHoldGalleryOpen,
|
||||||
shouldAutoSwitchToNewImages,
|
shouldAutoSwitchToNewImages,
|
||||||
areMoreImagesAvailable,
|
areMoreImagesAvailable,
|
||||||
|
galleryWidth,
|
||||||
} = useAppSelector(imageGallerySelector);
|
} = useAppSelector(imageGallerySelector);
|
||||||
|
|
||||||
const [gallerySize, setGallerySize] = useState<Size>({
|
const [galleryMinWidth, setGalleryMinWidth] = useState<number>(300);
|
||||||
width: '300',
|
const [galleryMaxWidth, setGalleryMaxWidth] = useState<number>(590);
|
||||||
height: '100%',
|
|
||||||
});
|
|
||||||
|
|
||||||
const [galleryMaxSize, setGalleryMaxSize] = useState<Size>({
|
const [shouldShowButtons, setShouldShowButtons] = useState<boolean>(
|
||||||
width: '590', // keep max at 590 for any tab
|
galleryWidth >= GALLERY_SHOW_BUTTONS_MIN_WIDTH
|
||||||
height: '100%',
|
);
|
||||||
});
|
|
||||||
|
|
||||||
const [galleryMinSize, setGalleryMinSize] = useState<Size>({
|
|
||||||
width: '300', // keep max at 590 for any tab
|
|
||||||
height: '100%',
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(gallerySize, galleryMaxSize, galleryMinSize);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (activeTabName === 'inpainting' && shouldPinGallery) {
|
if (!shouldPinGallery) return;
|
||||||
setGalleryMinSize((prevSize) => {
|
|
||||||
return { ...prevSize, width: 220 };
|
if (activeTabName === 'inpainting') {
|
||||||
});
|
dispatch(setGalleryWidth(220));
|
||||||
setGalleryMaxSize((prevSize) => {
|
setGalleryMinWidth(220);
|
||||||
return { ...prevSize, width: 220 };
|
setGalleryMaxWidth(220);
|
||||||
});
|
} else if (activeTabName === 'img2img') {
|
||||||
setGallerySize((prevSize) => {
|
dispatch(
|
||||||
return {
|
setGalleryWidth(Math.min(Math.max(Number(galleryWidth), 0), 490))
|
||||||
...prevSize,
|
);
|
||||||
width: Math.min(Math.max(Number(prevSize.width), 0), 220),
|
setGalleryMaxWidth(490);
|
||||||
};
|
|
||||||
});
|
|
||||||
} else if (activeTabName === 'img2img' && shouldPinGallery) {
|
|
||||||
setGalleryMaxSize((prevSize) => {
|
|
||||||
return { ...prevSize, width: 490, height: '100%' };
|
|
||||||
});
|
|
||||||
setGallerySize((prevSize) => {
|
|
||||||
return {
|
|
||||||
...prevSize,
|
|
||||||
width: Math.min(Math.max(Number(prevSize.width), 0), 490),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
setGalleryMaxSize((prevSize) => {
|
dispatch(
|
||||||
return { ...prevSize, width: 590, height: '100%' };
|
setGalleryWidth(Math.min(Math.max(Number(galleryWidth), 0), 590))
|
||||||
});
|
);
|
||||||
setGallerySize((prevSize) => {
|
setGalleryMaxWidth(590);
|
||||||
return {
|
|
||||||
...prevSize,
|
|
||||||
width: Math.min(Math.max(Number(prevSize.width), 0), 590),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, [activeTabName, shouldPinGallery]);
|
}, [dispatch, activeTabName, shouldPinGallery, galleryWidth]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!shouldPinGallery) {
|
if (!shouldPinGallery) {
|
||||||
setGalleryMaxSize((prevSize) => {
|
setGalleryMaxWidth(window.innerWidth);
|
||||||
// calculate vh in px
|
|
||||||
return {
|
|
||||||
...prevSize,
|
|
||||||
width: window.innerWidth,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, [shouldPinGallery]);
|
}, [shouldPinGallery]);
|
||||||
|
|
||||||
@ -126,10 +97,6 @@ export default function ImageGallery() {
|
|||||||
const handleSetShouldPinGallery = () => {
|
const handleSetShouldPinGallery = () => {
|
||||||
dispatch(setNeedsCache(true));
|
dispatch(setNeedsCache(true));
|
||||||
dispatch(setShouldPinGallery(!shouldPinGallery));
|
dispatch(setShouldPinGallery(!shouldPinGallery));
|
||||||
setGallerySize({
|
|
||||||
...gallerySize,
|
|
||||||
height: shouldPinGallery ? '100vh' : '100%',
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleToggleGallery = () => {
|
const handleToggleGallery = () => {
|
||||||
@ -300,9 +267,9 @@ export default function ImageGallery() {
|
|||||||
onMouseOver={!shouldPinGallery ? cancelCloseGalleryTimer : undefined}
|
onMouseOver={!shouldPinGallery ? cancelCloseGalleryTimer : undefined}
|
||||||
>
|
>
|
||||||
<Resizable
|
<Resizable
|
||||||
minWidth={galleryMinSize.width}
|
minWidth={galleryMinWidth}
|
||||||
maxWidth={galleryMaxSize.width}
|
maxWidth={galleryMaxWidth}
|
||||||
maxHeight={'100%'}
|
// maxHeight={'100%'}
|
||||||
className={'image-gallery-popup'}
|
className={'image-gallery-popup'}
|
||||||
handleStyles={{ left: { width: '15px' } }}
|
handleStyles={{ left: { width: '15px' } }}
|
||||||
enable={{
|
enable={{
|
||||||
@ -315,17 +282,25 @@ export default function ImageGallery() {
|
|||||||
bottomLeft: false,
|
bottomLeft: false,
|
||||||
topLeft: false,
|
topLeft: false,
|
||||||
}}
|
}}
|
||||||
size={gallerySize}
|
size={{
|
||||||
|
width: galleryWidth,
|
||||||
|
height: shouldPinGallery ? '100%' : '100vh',
|
||||||
|
}}
|
||||||
onResizeStop={(
|
onResizeStop={(
|
||||||
_event: MouseEvent | TouchEvent,
|
_event: MouseEvent | TouchEvent,
|
||||||
_direction: Direction,
|
_direction: Direction,
|
||||||
elementRef: HTMLElement,
|
elementRef: HTMLElement,
|
||||||
delta: NumberSize
|
delta: NumberSize
|
||||||
) => {
|
) => {
|
||||||
setGallerySize({
|
dispatch(
|
||||||
width: _.clamp(Number(gallerySize.width) + delta.width, 0, Number(galleryMaxSize.width)),
|
setGalleryWidth(
|
||||||
height: '100%',
|
_.clamp(
|
||||||
});
|
Number(galleryWidth) + delta.width,
|
||||||
|
0,
|
||||||
|
Number(galleryMaxWidth)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
elementRef.removeAttribute('data-resize-alert');
|
elementRef.removeAttribute('data-resize-alert');
|
||||||
}}
|
}}
|
||||||
onResize={(
|
onResize={(
|
||||||
@ -335,18 +310,21 @@ export default function ImageGallery() {
|
|||||||
delta: NumberSize
|
delta: NumberSize
|
||||||
) => {
|
) => {
|
||||||
const newWidth = _.clamp(
|
const newWidth = _.clamp(
|
||||||
Number(gallerySize.width) + delta.width,
|
Number(galleryWidth) + delta.width,
|
||||||
0,
|
0,
|
||||||
Number(galleryMaxSize.width)
|
Number(galleryMaxWidth)
|
||||||
);
|
);
|
||||||
if (newWidth >= galleryMaxSize.width) {
|
|
||||||
|
if (newWidth >= 320 && !shouldShowButtons) {
|
||||||
|
setShouldShowButtons(true);
|
||||||
|
} else if (newWidth < 320 && shouldShowButtons) {
|
||||||
|
setShouldShowButtons(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newWidth >= galleryMaxWidth) {
|
||||||
elementRef.setAttribute('data-resize-alert', 'true');
|
elementRef.setAttribute('data-resize-alert', 'true');
|
||||||
} else {
|
} else {
|
||||||
elementRef.removeAttribute('data-resize-alert');
|
elementRef.removeAttribute('data-resize-alert');
|
||||||
setGallerySize({
|
|
||||||
width: newWidth,
|
|
||||||
height: '100%',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -358,7 +336,7 @@ export default function ImageGallery() {
|
|||||||
variant="solid"
|
variant="solid"
|
||||||
className="image-gallery-category-btn-group"
|
className="image-gallery-category-btn-group"
|
||||||
>
|
>
|
||||||
{gallerySize.width > 320 ? (
|
{shouldShowButtons ? (
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
data-selected={currentCategory === 'result'}
|
data-selected={currentCategory === 'result'}
|
||||||
@ -393,6 +371,7 @@ export default function ImageGallery() {
|
|||||||
)}
|
)}
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
<IAIPopover
|
<IAIPopover
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
hasArrow={activeTabName === 'inpainting' ? false : true}
|
hasArrow={activeTabName === 'inpainting' ? false : true}
|
||||||
@ -451,7 +430,9 @@ export default function ImageGallery() {
|
|||||||
label="Auto-Switch to New Images"
|
label="Auto-Switch to New Images"
|
||||||
isChecked={shouldAutoSwitchToNewImages}
|
isChecked={shouldAutoSwitchToNewImages}
|
||||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||||
dispatch(setShouldAutoSwitchToNewImages(e.target.checked))
|
dispatch(
|
||||||
|
setShouldAutoSwitchToNewImages(e.target.checked)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -476,6 +457,7 @@ export default function ImageGallery() {
|
|||||||
icon={<MdClear />}
|
icon={<MdClear />}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div className="image-gallery-container" ref={galleryContainerRef}>
|
<div className="image-gallery-container" ref={galleryContainerRef}>
|
||||||
{images.length || areMoreImagesAvailable ? (
|
{images.length || areMoreImagesAvailable ? (
|
||||||
<>
|
<>
|
||||||
|
@ -36,6 +36,7 @@ export interface GalleryState {
|
|||||||
result: Gallery;
|
result: Gallery;
|
||||||
};
|
};
|
||||||
currentCategory: GalleryCategory;
|
currentCategory: GalleryCategory;
|
||||||
|
galleryWidth: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: GalleryState = {
|
const initialState: GalleryState = {
|
||||||
@ -62,6 +63,7 @@ const initialState: GalleryState = {
|
|||||||
areMoreImagesAvailable: true,
|
areMoreImagesAvailable: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
galleryWidth: 300,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const gallerySlice = createSlice({
|
export const gallerySlice = createSlice({
|
||||||
@ -248,6 +250,9 @@ export const gallerySlice = createSlice({
|
|||||||
setCurrentCategory: (state, action: PayloadAction<GalleryCategory>) => {
|
setCurrentCategory: (state, action: PayloadAction<GalleryCategory>) => {
|
||||||
state.currentCategory = action.payload;
|
state.currentCategory = action.payload;
|
||||||
},
|
},
|
||||||
|
setGalleryWidth: (state, action: PayloadAction<number>) => {
|
||||||
|
state.galleryWidth = action.payload;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -268,6 +273,7 @@ export const {
|
|||||||
setShouldHoldGalleryOpen,
|
setShouldHoldGalleryOpen,
|
||||||
setShouldAutoSwitchToNewImages,
|
setShouldAutoSwitchToNewImages,
|
||||||
setCurrentCategory,
|
setCurrentCategory,
|
||||||
|
setGalleryWidth,
|
||||||
} = gallerySlice.actions;
|
} = gallerySlice.actions;
|
||||||
|
|
||||||
export default gallerySlice.reducer;
|
export default gallerySlice.reducer;
|
||||||
|
@ -18,6 +18,7 @@ export const imageGallerySelector = createSelector(
|
|||||||
galleryImageObjectFit,
|
galleryImageObjectFit,
|
||||||
shouldHoldGalleryOpen,
|
shouldHoldGalleryOpen,
|
||||||
shouldAutoSwitchToNewImages,
|
shouldAutoSwitchToNewImages,
|
||||||
|
galleryWidth,
|
||||||
} = gallery;
|
} = gallery;
|
||||||
|
|
||||||
const { activeTab } = options;
|
const { activeTab } = options;
|
||||||
@ -37,6 +38,7 @@ export const imageGallerySelector = createSelector(
|
|||||||
areMoreImagesAvailable:
|
areMoreImagesAvailable:
|
||||||
categories[currentCategory].areMoreImagesAvailable,
|
categories[currentCategory].areMoreImagesAvailable,
|
||||||
currentCategory,
|
currentCategory,
|
||||||
|
galleryWidth,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user